Merge lp:~abreu-alexandre/oxide/add-download-requested-support into lp:~oxide-developers/oxide/oxide.trunk

Proposed by Alexandre Abreu
Status: Merged
Merged at revision: 628
Proposed branch: lp:~abreu-alexandre/oxide/add-download-requested-support
Merge into: lp:~oxide-developers/oxide/oxide.trunk
Diff against target: 1088 lines (+803/-1)
23 files modified
patches/add-should-download-url-to-resource-dispatcher-host.patch (+125/-0)
patches/series (+1/-0)
qt/core/api/oxideqdownloadrequest.cc (+98/-0)
qt/core/api/oxideqdownloadrequest.h (+66/-0)
qt/core/api/oxideqdownloadrequest_p.h (+51/-0)
qt/core/browser/oxide_qt_web_view.cc (+20/-0)
qt/core/browser/oxide_qt_web_view.h (+7/-0)
qt/core/core.gyp (+9/-0)
qt/core/glue/oxide_qt_web_view_adapter.h (+3/-0)
qt/quick/api/oxideqquickwebview.cc (+7/-0)
qt/quick/api/oxideqquickwebview_p.h (+2/-0)
qt/quick/api/oxideqquickwebview_p_p.h (+2/-0)
qt/quick/oxide_qml_plugin.cc (+3/-0)
qt/tests/qmltests/api/tst_WebView_downloadRequested.py (+20/-0)
qt/tests/qmltests/api/tst_WebView_downloadRequested.qml (+58/-0)
qt/tests/qmltests/api/tst_WebView_downloadRequestedUnhandledMimeType.py (+18/-0)
shared/browser/oxide_content_browser_client.cc (+8/-0)
shared/browser/oxide_content_browser_client.h (+15/-1)
shared/browser/oxide_resource_dispatcher_host_delegate.cc (+162/-0)
shared/browser/oxide_resource_dispatcher_host_delegate.h (+92/-0)
shared/browser/oxide_web_view.cc (+18/-0)
shared/browser/oxide_web_view.h (+16/-0)
shared/shared.gyp (+2/-0)
To merge this branch: bzr merge lp:~abreu-alexandre/oxide/add-download-requested-support
Reviewer Review Type Date Requested Status
Chris Coulson Approve
Review via email: mp+223333@code.launchpad.net

Commit message

First part of the download support. For now it delegates all download requests to the embedder.

Description of the change

First part of the download support. For now it delegates all download requests to the embedder.

To post a comment you must log in.
614. By Chris Coulson

GetViewBounds() only works when a RenderViewItem is added to a scene

615. By Chris Coulson

Actually make onWindowChanged a slot

616. By Chris Coulson

Bump Chromium rev to 37.0.2054.3

617. By Chris Coulson

Force Qt focus object changed events when the oxide focused node changes

618. By Alexandre Abreu

add devtools support

619. By Chris Coulson

Expose a Flickable-like API on the QML WebView, with content{Width,Height,X,Y} and viewport{Width,Height} attributes

620. By Chris Coulson

Stop using deprecated compositing paths by using a delegating renderer compositor alongside a synchronous browser compositor. Eventually we will delegate this to the Qml scenegraph compositor, although the extra browser compositor will still be useful for a fallback path (and for other ports of Oxide, should they happen)

621. By Chris Coulson

Evict the delegated frame and front buffer for hidden webviews

622. By Chris Coulson

Remove spurious printf

623. By Chris Coulson

Don't crash on shutdown when devtools isn't enabled

624. By Chris Coulson

Bump Chromium rev to 37.0.2062.0

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Ok, I've added some comments to this. It's fairly close already. One thing we do need though are some unit tests

review: Needs Fixing
Revision history for this message
Alexandre Abreu (abreu-alexandre) :
Revision history for this message
Alexandre Abreu (abreu-alexandre) wrote :

Updated

Revision history for this message
Alexandre Abreu (abreu-alexandre) wrote :

Added some tests

625. By Alexandre Abreu

add download support

626. By Alexandre Abreu

update patch

Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

The referrer currently appears to be missing the protocol (e.g. I get "mail.google.com/mail/mu/mp/30/" instead of "https://mail.google.com/mail/mu/mp/30/")

627. By Alexandre Abreu

add right reference to referrer

628. By Alexandre Abreu

send back the full url for the referrer

Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

At the moment the request.cookies list appears to just contains one entry with all the semi-colon delimited cookies in it which I'm guessing wasn't the intent? I think this is due to splitting on "," instead of ";" (added in-line comment for this)

629. By Alexandre Abreu

make sure that multiple cookies are properly split

Revision history for this message
Chris Coulson (chrisccoulson) wrote :

Ok, that looks fine. Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'patches/add-should-download-url-to-resource-dispatcher-host.patch'
2--- patches/add-should-download-url-to-resource-dispatcher-host.patch 1970-01-01 00:00:00 +0000
3+++ patches/add-should-download-url-to-resource-dispatcher-host.patch 2014-06-27 18:46:24 +0000
4@@ -0,0 +1,125 @@
5+# Description: Add a ShouldDownloadUrl embedder hook to dispatch download requests.
6+# Author: Alexandre Abreu <alexandre.abreu@canonical.com>
7+
8+diff --git a/content/browser/loader/buffered_resource_handler.cc b/content/browser/loader/buffered_resource_handler.cc
9+--- a/content/browser/loader/buffered_resource_handler.cc
10++++ b/content/browser/loader/buffered_resource_handler.cc
11+@@ -10,6 +10,7 @@
12+ #include "base/logging.h"
13+ #include "base/metrics/histogram.h"
14+ #include "base/strings/string_util.h"
15++#include "base/strings/utf_string_conversions.h"
16+ #include "content/browser/download/download_resource_handler.h"
17+ #include "content/browser/download/download_stats.h"
18+ #include "content/browser/loader/certificate_resource_handler.h"
19+@@ -341,6 +342,36 @@
20+ #endif
21+ }
22+
23++ if (host_->delegate()) {
24++ std::string disposition;
25++ request()->GetResponseHeaderByName(
26++ "content-disposition", &disposition);
27++ net::HttpContentDisposition
28++ content_disposition(disposition, std::string());
29++ ResourceRequestInfoImpl* info = GetRequestInfo();
30++ if (!host_->delegate()->ShouldDownloadUrl(
31++ request()->url(),
32++ request()->first_party_for_cookies(),
33++ info->HasUserGesture(),
34++ !disposition.empty() &&
35++ (content_disposition.parse_result_flags() & net::HttpContentDisposition::HAS_FILENAME)
36++ ? base::UTF8ToUTF16(content_disposition.filename())
37++ : base::string16(),
38++ false,
39++ Referrer(GURL(request()->referrer()), info->GetReferrerPolicy()),
40++ response_->head.mime_type,
41++ info->GetChildID(),
42++ info->GetRouteID(),
43++ info->GetContext())) {
44++ request()->Cancel();
45++ Cancel();
46++ LOG(INFO) << "Download request for "
47++ << request()->url().GetContent()
48++ << " got cancelled by embedder";
49++ return false;
50++ }
51++ }
52++
53+ // Install download handler
54+ info->set_is_download(true);
55+ scoped_ptr<ResourceHandler> handler(
56+diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
57+--- a/content/browser/loader/resource_dispatcher_host_impl.cc
58++++ b/content/browser/loader/resource_dispatcher_host_impl.cc
59+@@ -493,6 +493,23 @@
60+ DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN);
61+
62+ const GURL& url = request->original_url();
63++ if (delegate_) {
64++ bool should_download_url = delegate_->ShouldDownloadUrl(
65++ url,
66++ request->first_party_for_cookies(),
67++ is_content_initiated,
68++ save_info->suggested_name,
69++ save_info->prompt_for_save_location,
70++ referrer,
71++ std::string(), // mime_type
72++ child_id,
73++ route_id,
74++ context);
75++ if (!should_download_url) {
76++ return CallbackAndReturn(started_callback,
77++ DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN);
78++ }
79++ }
80+
81+ // http://crbug.com/90971
82+ char url_buf[128];
83+diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc
84+--- a/content/public/browser/resource_dispatcher_host_delegate.cc
85++++ b/content/public/browser/resource_dispatcher_host_delegate.cc
86+@@ -96,6 +96,20 @@
87+ net::URLRequest* url_request) {
88+ }
89+
90++bool ResourceDispatcherHostDelegate::ShouldDownloadUrl(
91++ const GURL& url,
92++ const GURL& first_party_url,
93++ bool is_content_initiated,
94++ const base::string16& suggested_name,
95++ const bool use_prompt,
96++ const Referrer& referrer,
97++ const std::string& mime_type,
98++ int render_process_id,
99++ int render_view_id,
100++ ResourceContext* resource_context) {
101++ return true;
102++}
103++
104+ ResourceDispatcherHostDelegate::ResourceDispatcherHostDelegate() {
105+ }
106+
107+diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h
108+--- a/content/public/browser/resource_dispatcher_host_delegate.h
109++++ b/content/public/browser/resource_dispatcher_host_delegate.h
110+@@ -140,6 +141,19 @@
111+ // Notification that a request has completed.
112+ virtual void RequestComplete(net::URLRequest* url_request);
113+
114++ // Returns whether a given download request should be carried on.
115++ virtual bool ShouldDownloadUrl(
116++ const GURL& url,
117++ const GURL& first_party_url,
118++ bool is_content_initiated,
119++ const base::string16& suggested_name,
120++ const bool use_prompt,
121++ const Referrer& referrer,
122++ const std::string& mime_type,
123++ int render_process_id,
124++ int render_view_id,
125++ ResourceContext* resource_context);
126++
127+ protected:
128+ ResourceDispatcherHostDelegate();
129+ virtual ~ResourceDispatcherHostDelegate();
130
131=== modified file 'patches/series'
132--- patches/series 2014-06-06 16:07:21 +0000
133+++ patches/series 2014-06-27 18:46:24 +0000
134@@ -14,3 +14,4 @@
135 expose-extra-properties-for-should-create-webcontents.patch
136 disable-default-network-location-provider.patch
137 use-gles-api.patch
138+add-should-download-url-to-resource-dispatcher-host.patch
139
140=== added file 'qt/core/api/oxideqdownloadrequest.cc'
141--- qt/core/api/oxideqdownloadrequest.cc 1970-01-01 00:00:00 +0000
142+++ qt/core/api/oxideqdownloadrequest.cc 2014-06-27 18:46:24 +0000
143@@ -0,0 +1,98 @@
144+// vim:expandtab:shiftwidth=2:tabstop=2:
145+// Copyright (C) 2014 Canonical Ltd.
146+
147+// This library is free software; you can redistribute it and/or
148+// modify it under the terms of the GNU Lesser General Public
149+// License as published by the Free Software Foundation; either
150+// version 2.1 of the License, or (at your option) any later version.
151+
152+// This library is distributed in the hope that it will be useful,
153+// but WITHOUT ANY WARRANTY; without even the implied warranty of
154+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
155+// Lesser General Public License for more details.
156+
157+// You should have received a copy of the GNU Lesser General Public
158+// License along with this library; if not, write to the Free Software
159+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
160+
161+#include "oxideqdownloadrequest.h"
162+#include "oxideqdownloadrequest_p.h"
163+
164+#include "net/http/http_request_headers.h"
165+#include "url/gurl.h"
166+
167+namespace {
168+const QString kCookieListDelimiter = ";";
169+}
170+
171+OxideQDownloadRequestPrivate::OxideQDownloadRequestPrivate(
172+ const QUrl& url,
173+ const QString& mimeType,
174+ const bool shouldPrompt,
175+ const QString& suggestedFilename,
176+ const QStringList& cookies,
177+ const QString& referrer)
178+ : url_(url),
179+ mime_type_(mimeType),
180+ should_prompt_(shouldPrompt),
181+ suggested_filename_(suggestedFilename),
182+ cookies_(cookies),
183+ referrer_(referrer) {}
184+
185+OxideQDownloadRequestPrivate::~OxideQDownloadRequestPrivate() {}
186+
187+OxideQDownloadRequest::OxideQDownloadRequest(
188+ const QUrl& url,
189+ const QString& mimeType,
190+ const bool shouldPrompt,
191+ const QString& suggestedFilename,
192+ const QString& cookies,
193+ const QString& referrer,
194+ QObject* parent) :
195+ QObject(parent),
196+ d_ptr(new OxideQDownloadRequestPrivate(url,
197+ mimeType,
198+ shouldPrompt,
199+ suggestedFilename,
200+ cookies.split(kCookieListDelimiter, QString::SkipEmptyParts),
201+ referrer)) {
202+}
203+
204+OxideQDownloadRequest::~OxideQDownloadRequest() {}
205+
206+QUrl OxideQDownloadRequest::url() const {
207+ Q_D(const OxideQDownloadRequest);
208+
209+ return d->url_;
210+}
211+
212+QString OxideQDownloadRequest::mimeType() const {
213+ Q_D(const OxideQDownloadRequest);
214+
215+ return d->mime_type_;
216+}
217+
218+bool OxideQDownloadRequest::shouldPrompt() const {
219+ Q_D(const OxideQDownloadRequest);
220+
221+ return d->should_prompt_;
222+}
223+
224+QString OxideQDownloadRequest::suggestedFilename() const {
225+ Q_D(const OxideQDownloadRequest);
226+
227+ return d->suggested_filename_;
228+}
229+
230+QStringList OxideQDownloadRequest::cookies() const {
231+ Q_D(const OxideQDownloadRequest);
232+
233+ return d->cookies_;
234+}
235+
236+QString OxideQDownloadRequest::referrer() const {
237+ Q_D(const OxideQDownloadRequest);
238+
239+ return d->referrer_;
240+}
241+
242
243=== added file 'qt/core/api/oxideqdownloadrequest.h'
244--- qt/core/api/oxideqdownloadrequest.h 1970-01-01 00:00:00 +0000
245+++ qt/core/api/oxideqdownloadrequest.h 2014-06-27 18:46:24 +0000
246@@ -0,0 +1,66 @@
247+// vim:expandtab:shiftwidth=2:tabstop=2:
248+// Copyright (C) 2014 Canonical Ltd.
249+
250+// This library is free software; you can redistribute it and/or
251+// modify it under the terms of the GNU Lesser General Public
252+// License as published by the Free Software Foundation; either
253+// version 2.1 of the License, or (at your option) any later version.
254+
255+// This library is distributed in the hope that it will be useful,
256+// but WITHOUT ANY WARRANTY; without even the implied warranty of
257+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
258+// Lesser General Public License for more details.
259+
260+// You should have received a copy of the GNU Lesser General Public
261+// License along with this library; if not, write to the Free Software
262+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
263+
264+#ifndef OXIDE_Q_DOWNLOAD_REQUEST
265+#define OXIDE_Q_DOWNLOAD_REQUEST
266+
267+#include <QObject>
268+#include <QScopedPointer>
269+#include <QString>
270+#include <QStringList>
271+#include <QtGlobal>
272+#include <QUrl>
273+
274+class OxideQDownloadRequestPrivate;
275+
276+class Q_DECL_EXPORT OxideQDownloadRequest : public QObject {
277+ Q_OBJECT
278+
279+ Q_PROPERTY(QUrl url READ url CONSTANT)
280+ Q_PROPERTY(QString mimeType READ mimeType CONSTANT)
281+ Q_PROPERTY(bool shouldPrompt READ shouldPrompt CONSTANT)
282+ Q_PROPERTY(QString suggestedFilename READ suggestedFilename CONSTANT)
283+ Q_PROPERTY(QStringList cookies READ cookies CONSTANT)
284+ Q_PROPERTY(QString referrer READ referrer CONSTANT)
285+
286+ Q_DECLARE_PRIVATE(OxideQDownloadRequest)
287+ Q_DISABLE_COPY(OxideQDownloadRequest)
288+
289+ public:
290+ OxideQDownloadRequest(
291+ const QUrl& url,
292+ const QString& mimeType,
293+ const bool shouldPrompt,
294+ const QString& suggestedFilename,
295+ const QString& cookies,
296+ const QString& referrer,
297+ QObject* parent = 0);
298+ virtual ~OxideQDownloadRequest();
299+
300+ QUrl url() const;
301+ QString mimeType() const;
302+ bool shouldPrompt() const;
303+ QString suggestedFilename() const;
304+ QStringList cookies() const;
305+ QString referrer() const;
306+
307+ private:
308+
309+ QScopedPointer<OxideQDownloadRequestPrivate> d_ptr;
310+};
311+
312+#endif // OXIDE_Q_DOWNLOAD_REQUEST
313
314=== added file 'qt/core/api/oxideqdownloadrequest_p.h'
315--- qt/core/api/oxideqdownloadrequest_p.h 1970-01-01 00:00:00 +0000
316+++ qt/core/api/oxideqdownloadrequest_p.h 2014-06-27 18:46:24 +0000
317@@ -0,0 +1,51 @@
318+// vim:expandtab:shiftwidth=2:tabstop=2:
319+// Copyright (C) 2014 Canonical Ltd.
320+
321+// This library is free software; you can redistribute it and/or
322+// modify it under the terms of the GNU Lesser General Public
323+// License as published by the Free Software Foundation; either
324+// version 2.1 of the License, or (at your option) any later version.
325+
326+// This library is distributed in the hope that it will be useful,
327+// but WITHOUT ANY WARRANTY; without even the implied warranty of
328+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
329+// Lesser General Public License for more details.
330+
331+// You should have received a copy of the GNU Lesser General Public
332+// License along with this library; if not, write to the Free Software
333+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
334+
335+#ifndef _OXIDE_QT_CORE_API_DOWNLOAD_REQUEST_P_H_
336+#define _OXIDE_QT_CORE_API_DOWNLOAD_REQUEST_P_H_
337+
338+#include <QtGlobal>
339+#include <QString>
340+#include <QStringList>
341+#include <QUrl>
342+
343+class OxideQDownloadRequest;
344+
345+class OxideQDownloadRequestPrivate {
346+ public:
347+ OxideQDownloadRequestPrivate(
348+ const QUrl& url,
349+ const QString& mimeType,
350+ const bool shouldPrompt,
351+ const QString& suggestedFilename,
352+ const QStringList& cookies,
353+ const QString& referrer);
354+ virtual ~OxideQDownloadRequestPrivate();
355+
356+ private:
357+ friend class OxideQDownloadRequest;
358+
359+ QUrl url_;
360+ QString mime_type_;
361+ bool should_prompt_;
362+ QString suggested_filename_;
363+ QStringList cookies_;
364+ QString referrer_;
365+};
366+
367+#endif // _OXIDE_QT_CORE_API_DOWNLOAD_REQUEST_P_H_
368+
369
370=== modified file 'qt/core/browser/oxide_qt_web_view.cc'
371--- qt/core/browser/oxide_qt_web_view.cc 2014-06-23 15:10:54 +0000
372+++ qt/core/browser/oxide_qt_web_view.cc 2014-06-27 18:46:24 +0000
373@@ -29,6 +29,7 @@
374 #include "net/base/net_errors.h"
375 #include "content/public/browser/native_web_keyboard_event.h"
376
377+#include "qt/core/api/oxideqdownloadrequest.h"
378 #include "qt/core/api/oxideqloadevent.h"
379 #include "qt/core/api/oxideqnavigationrequest.h"
380 #include "qt/core/api/oxideqnewviewrequest.h"
381@@ -389,6 +390,25 @@
382 return view;
383 }
384
385+void WebView::OnDownloadRequested(const GURL& url,
386+ const std::string& mimeType,
387+ const bool shouldPrompt,
388+ const base::string16& suggestedFilename,
389+ const std::string& cookies,
390+ const std::string& referrer) {
391+ OxideQDownloadRequest
392+ downloadRequest(
393+ QUrl(QString::fromStdString(url.spec())),
394+ QString::fromStdString(mimeType),
395+ shouldPrompt,
396+ QString::fromStdString(base::UTF16ToUTF8(suggestedFilename)),
397+ QString::fromStdString(cookies),
398+ QString::fromStdString(referrer));
399+
400+ adapter_->DownloadRequested(&downloadRequest);
401+}
402+
403+
404 // static
405 WebView* WebView::Create(WebViewAdapter* adapter) {
406 return new WebView(adapter);
407
408=== modified file 'qt/core/browser/oxide_qt_web_view.h'
409--- qt/core/browser/oxide_qt_web_view.h 2014-06-23 15:10:54 +0000
410+++ qt/core/browser/oxide_qt_web_view.h 2014-06-27 18:46:24 +0000
411@@ -113,6 +113,13 @@
412 WindowOpenDisposition disposition,
413 bool user_gesture) FINAL;
414
415+ void OnDownloadRequested(const GURL& url,
416+ const std::string& mimeType,
417+ const bool shouldPrompt,
418+ const base::string16& suggestedFilename,
419+ const std::string& cookies,
420+ const std::string& referrer) FINAL;
421+
422 oxide::WebFrame* CreateWebFrame(content::FrameTreeNode* node) FINAL;
423
424 oxide::WebView* CreateNewWebView(const gfx::Rect& initial_pos,
425
426=== modified file 'qt/core/core.gyp'
427--- qt/core/core.gyp 2014-06-24 19:21:21 +0000
428+++ qt/core/core.gyp 2014-06-27 18:46:24 +0000
429@@ -128,6 +128,7 @@
430 '<(DEPTH)'
431 ],
432 'sources': [
433+ '<(INTERMEDIATE_DIR)/moc_oxideqdownloadrequest.cc',
434 '<(INTERMEDIATE_DIR)/moc_oxideqloadevent.cc',
435 '<(INTERMEDIATE_DIR)/moc_oxideqnetworkcallbackevents.cc',
436 '<(INTERMEDIATE_DIR)/moc_oxideqnavigationrequest.cc',
437@@ -135,6 +136,9 @@
438 '<(INTERMEDIATE_DIR)/moc_oxideqpermissionrequest.cc',
439 '<(INTERMEDIATE_DIR)/moc_oxideqstoragepermissionrequest.cc',
440 '<(INTERMEDIATE_DIR)/moc_oxideqwebpreferences.cc',
441+ 'api/oxideqdownloadrequest.cc',
442+ 'api/oxideqdownloadrequest.h',
443+ 'api/oxideqdownloadrequest_p.h',
444 'api/oxideqloadevent.cc',
445 'api/oxideqloadevent.h',
446 'api/oxideqloadevent_p.h',
447@@ -187,6 +191,11 @@
448 ],
449 'actions': [
450 {
451+ 'action_name': 'moc_oxideqdownloadrequest.cc',
452+ 'moc_input': 'api/oxideqdownloadrequest.h',
453+ 'includes': [ 'moc.gypi' ]
454+ },
455+ {
456 'action_name': 'moc_oxideqloadevent.cc',
457 'moc_input': 'api/oxideqloadevent.h',
458 'includes': [ 'moc.gypi' ]
459
460=== modified file 'qt/core/glue/oxide_qt_web_view_adapter.h'
461--- qt/core/glue/oxide_qt_web_view_adapter.h 2014-06-24 14:54:27 +0000
462+++ qt/core/glue/oxide_qt_web_view_adapter.h 2014-06-27 18:46:24 +0000
463@@ -36,6 +36,7 @@
464 class QSize;
465 QT_END_NAMESPACE
466
467+class OxideQDownloadRequest;
468 class OxideQGeolocationPermissionRequest;
469 class OxideQLoadEvent;
470 class OxideQNavigationRequest;
471@@ -191,6 +192,8 @@
472
473 virtual void HandleKeyboardEvent(QKeyEvent* event) = 0;
474
475+ virtual void DownloadRequested(OxideQDownloadRequest* downloadRequest) = 0;
476+
477 QScopedPointer<WebView> priv;
478 QList<ScriptMessageHandlerAdapter *> message_handlers_;
479 QScopedPointer<ConstructProperties> construct_props_;
480
481=== modified file 'qt/quick/api/oxideqquickwebview.cc'
482--- qt/quick/api/oxideqquickwebview.cc 2014-06-23 15:10:54 +0000
483+++ qt/quick/api/oxideqquickwebview.cc 2014-06-27 18:46:24 +0000
484@@ -344,6 +344,13 @@
485 w->sendEvent(q, event);
486 }
487
488+void OxideQQuickWebViewPrivate::DownloadRequested(
489+ OxideQDownloadRequest* downloadRequest) {
490+ Q_Q(OxideQQuickWebView);
491+
492+ emit q->downloadRequested(downloadRequest);
493+}
494+
495 void OxideQQuickWebViewPrivate::completeConstruction() {
496 Q_Q(OxideQQuickWebView);
497
498
499=== modified file 'qt/quick/api/oxideqquickwebview_p.h'
500--- qt/quick/api/oxideqquickwebview_p.h 2014-06-20 17:07:39 +0000
501+++ qt/quick/api/oxideqquickwebview_p.h 2014-06-27 18:46:24 +0000
502@@ -43,6 +43,7 @@
503 class OxideQQuickWebFrame;
504 class OxideQQuickWebView;
505 class OxideQQuickWebViewPrivate;
506+class OxideQDownloadRequest;
507
508 class OxideQQuickWebViewAttached : public QObject {
509 Q_OBJECT
510@@ -223,6 +224,7 @@
511 const QString& message,
512 int lineNumber,
513 const QString& sourceId);
514+ void downloadRequested(OxideQDownloadRequest* request);
515
516 private:
517 Q_PRIVATE_SLOT(d_func(), void contextConstructed());
518
519=== modified file 'qt/quick/api/oxideqquickwebview_p_p.h'
520--- qt/quick/api/oxideqquickwebview_p_p.h 2014-06-23 15:10:54 +0000
521+++ qt/quick/api/oxideqquickwebview_p_p.h 2014-06-27 18:46:24 +0000
522@@ -107,6 +107,8 @@
523
524 void HandleKeyboardEvent(QKeyEvent *event) Q_DECL_FINAL;
525
526+ void DownloadRequested(OxideQDownloadRequest* downloadRequest) Q_DECL_FINAL;
527+
528 void completeConstruction();
529
530 static void messageHandler_append(
531
532=== modified file 'qt/quick/oxide_qml_plugin.cc'
533--- qt/quick/oxide_qml_plugin.cc 2014-05-07 14:06:05 +0000
534+++ qt/quick/oxide_qml_plugin.cc 2014-06-27 18:46:24 +0000
535@@ -21,6 +21,7 @@
536 #include <QQmlEngine>
537 #include <QQmlExtensionPlugin>
538
539+#include "qt/core/api/oxideqdownloadrequest.h"
540 #include "qt/core/api/oxideqloadevent.h"
541 #include "qt/core/api/oxideqnavigationrequest.h"
542 #include "qt/core/api/oxideqnewviewrequest.h"
543@@ -78,6 +79,8 @@
544 "OutgoingMessageRequests are created automatically by WebFrame.sendMessage");
545 qmlRegisterUncreatableType<OxideQQuickWebFrame>(uri, 1, 0, "WebFrame",
546 "Frames are created automatically by Oxide to represent frames in the renderer");
547+ qmlRegisterUncreatableType<OxideQDownloadRequest>(uri, 1, 0, "DownloadRequest",
548+ "Cannot create separate instance of DownloadRequest");
549
550 qmlRegisterType<OxideQQuickScriptMessageHandler>(uri, 1, 0, "ScriptMessageHandler");
551 qmlRegisterType<OxideQQuickUserScript>(uri, 1, 0, "UserScript");
552
553=== added file 'qt/tests/qmltests/api/tst_WebView_downloadRequested.py'
554--- qt/tests/qmltests/api/tst_WebView_downloadRequested.py 1970-01-01 00:00:00 +0000
555+++ qt/tests/qmltests/api/tst_WebView_downloadRequested.py 2014-06-27 18:46:24 +0000
556@@ -0,0 +1,20 @@
557+from cStringIO import StringIO
558+from datetime import datetime, timedelta
559+
560+def handler(request):
561+ html = StringIO()
562+ html.write("<html></html>");
563+
564+ expires = datetime.utcnow()
565+ expires += timedelta(hours=100)
566+
567+ request.send_response(200)
568+ request.send_header("Content-Type", "text/html")
569+ request.send_header("Content-Length", html.tell())
570+ request.send_header("Cache-Control", "private")
571+ request.send_header("Content-Disposition", "attachment; filename=001.html")
572+ request.send_header("Set-Cookie", "foo=bar;Expires=%s;Domain=;Path=/" % expires.strftime("%a, %d-%b-%Y %H-%M-%S UTC"))
573+ request.send_header("Set-Cookie", "bar=bazz")
574+ request.end_headers()
575+
576+ request.wfile.write(html.getvalue())
577
578=== added file 'qt/tests/qmltests/api/tst_WebView_downloadRequested.qml'
579--- qt/tests/qmltests/api/tst_WebView_downloadRequested.qml 1970-01-01 00:00:00 +0000
580+++ qt/tests/qmltests/api/tst_WebView_downloadRequested.qml 2014-06-27 18:46:24 +0000
581@@ -0,0 +1,58 @@
582+import QtQuick 2.0
583+import QtTest 1.0
584+import com.canonical.Oxide 1.0
585+import com.canonical.Oxide.Testing 1.0
586+
587+TestWebView {
588+ id: webView
589+ focus: true
590+ width: 200
591+ height: 200
592+
593+ property string latestDownloadUrl: ""
594+ property string latestSuggestedFilename: ""
595+ property var latestCookies
596+ property string latestMimeType: ""
597+ property string latestReferrer: ""
598+
599+ onDownloadRequested: {
600+ latestDownloadUrl = request.url;
601+ latestCookies = [].slice.call(request.cookies).join(",");
602+ latestMimeType = request.mimeType;
603+ latestSuggestedFilename = request.suggestedFilename;
604+ latestReferrer = request.referrer;
605+ }
606+
607+ SignalSpy {
608+ id: spy
609+ target: webView
610+ signalName: "downloadRequested"
611+ }
612+
613+ TestCase {
614+ name: "WebView_downloadRequest"
615+ when: windowShown
616+
617+ function test_WebView_downloadRequestWithContentDisposition() {
618+ webView.url = "http://localhost:8080/tst_WebView_downloadRequested.py"
619+ verify(webView.waitForLoadStopped(),
620+ "Timed out waiting for a successful load");
621+
622+ compare(spy.count, 1)
623+ compare(webView.latestMimeType, "text/html")
624+ compare(webView.latestCookies, "foo=bar, bar=bazz")
625+ compare(webView.latestSuggestedFilename, "001.html")
626+ }
627+
628+ function test_WebView_downloadRequestUnhandledMimeType() {
629+ webView.url = "http://localhost:8080/tst_WebView_downloadRequestedUnhandledMimeType.py"
630+ verify(webView.waitForLoadStopped(),
631+ "Timed out waiting for a successful load");
632+
633+ compare(spy.count, 1)
634+ compare(webView.latestMimeType, "application/pdf")
635+ compare(webView.latestCookies, "foo=bar")
636+ compare(webView.latestSuggestedFilename, "")
637+ }
638+ }
639+}
640
641=== added file 'qt/tests/qmltests/api/tst_WebView_downloadRequestedUnhandledMimeType.py'
642--- qt/tests/qmltests/api/tst_WebView_downloadRequestedUnhandledMimeType.py 1970-01-01 00:00:00 +0000
643+++ qt/tests/qmltests/api/tst_WebView_downloadRequestedUnhandledMimeType.py 2014-06-27 18:46:24 +0000
644@@ -0,0 +1,18 @@
645+from cStringIO import StringIO
646+from datetime import datetime, timedelta
647+
648+def handler(request):
649+ html = StringIO()
650+ html.write("<html></html>");
651+
652+ expires = datetime.utcnow()
653+ expires += timedelta(hours=100)
654+
655+ request.send_response(200)
656+ request.send_header("Content-Type", "application/pdf")
657+ request.send_header("Content-Length", html.tell())
658+ request.send_header("Cache-Control", "private")
659+ request.send_header("Set-Cookie", "foo=bar;Expires=%s;Domain=;Path=/" % expires.strftime("%a, %d-%b-%Y %H-%M-%S UTC"))
660+ request.end_headers()
661+
662+ request.wfile.write(html.getvalue())
663
664=== modified file 'shared/browser/oxide_content_browser_client.cc'
665--- shared/browser/oxide_content_browser_client.cc 2014-06-24 19:21:21 +0000
666+++ shared/browser/oxide_content_browser_client.cc 2014-06-27 18:46:24 +0000
667@@ -30,6 +30,7 @@
668 #include "content/browser/gpu/gpu_process_host.h"
669 #include "content/public/browser/browser_main_parts.h"
670 #include "content/public/browser/render_process_host.h"
671+#include "content/public/browser/resource_dispatcher_host.h"
672 #include "content/public/common/content_switches.h"
673 #include "net/base/net_module.h"
674 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
675@@ -55,6 +56,7 @@
676 #include "oxide_form_factor.h"
677 #include "oxide_io_thread.h"
678 #include "oxide_message_pump.h"
679+#include "oxide_resource_dispatcher_host_delegate.h"
680 #include "oxide_script_message_dispatcher_browser.h"
681 #include "oxide_user_agent_override_provider.h"
682 #include "oxide_web_preferences.h"
683@@ -410,6 +412,12 @@
684 return false;
685 }
686
687+void ContentBrowserClient::ResourceDispatcherHostCreated() {
688+ resource_dispatcher_host_delegate_.reset(new ResourceDispatcherHostDelegate());
689+ content::ResourceDispatcherHost::Get()->SetDelegate(
690+ resource_dispatcher_host_delegate_.get());
691+}
692+
693 ContentBrowserClient::ContentBrowserClient() {}
694
695 ContentBrowserClient::~ContentBrowserClient() {}
696
697=== modified file 'shared/browser/oxide_content_browser_client.h'
698--- shared/browser/oxide_content_browser_client.h 2014-06-19 17:41:21 +0000
699+++ shared/browser/oxide_content_browser_client.h 2014-06-27 18:46:24 +0000
700@@ -23,7 +23,15 @@
701 #include "base/basictypes.h"
702 #include "base/compiler_specific.h"
703 #include "base/memory/ref_counted.h"
704-#include "content/public/browser/content_browser_client.h"
705+#include "base/memory/scoped_ptr.h"
706+#include "content/public/browser/content_browser_client.h"
707+
708+#include "base/observer_list.h"
709+#include "base/synchronization/lock.h"
710+#include "content/public/browser/browser_context.h"
711+#include "content/public/browser/content_browser_client.h"
712+#include "content/public/browser/cookie_store_factory.h"
713+#include "net/base/static_cookie_policy.h"
714
715 namespace base {
716 class MessagePump;
717@@ -31,6 +39,7 @@
718
719 namespace content {
720 class RenderViewHost;
721+class ResourceDispatcherHostDelegate;
722 }
723
724 namespace gfx {
725@@ -40,6 +49,7 @@
726 namespace oxide {
727
728 class GLShareGroup;
729+class ResourceDispatcherHostDelegate;
730 class SharedGLContext;
731 class WebFrameTree;
732 class WebPreferences;
733@@ -136,6 +146,10 @@
734 // Should be subclassed
735 virtual bool IsTouchSupported();
736
737+ virtual void ResourceDispatcherHostCreated() FINAL;
738+
739+ scoped_ptr<oxide::ResourceDispatcherHostDelegate> resource_dispatcher_host_delegate_;
740+
741 DISALLOW_COPY_AND_ASSIGN(ContentBrowserClient);
742 };
743
744
745=== added file 'shared/browser/oxide_resource_dispatcher_host_delegate.cc'
746--- shared/browser/oxide_resource_dispatcher_host_delegate.cc 1970-01-01 00:00:00 +0000
747+++ shared/browser/oxide_resource_dispatcher_host_delegate.cc 2014-06-27 18:46:24 +0000
748@@ -0,0 +1,162 @@
749+// vim:expandtab:shiftwidth=2:tabstop=2:
750+// Copyright (C) 2014 Canonical Ltd.
751+
752+// This library is free software; you can redistribute it and/or
753+// modify it under the terms of the GNU Lesser General Public
754+// License as published by the Free Software Foundation; either
755+// version 2.1 of the License, or (at your option) any later version.
756+
757+// This library is distributed in the hope that it will be useful,
758+// but WITHOUT ANY WARRANTY; without even the implied warranty of
759+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
760+// Lesser General Public License for more details.
761+
762+// You should have received a copy of the GNU Lesser General Public
763+// License along with this library; if not, write to the Free Software
764+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
765+
766+#include "oxide_resource_dispatcher_host_delegate.h"
767+
768+#include "base/bind.h"
769+#include "base/callback.h"
770+#include "base/logging.h"
771+#include "base/memory/ref_counted.h"
772+#include "content/browser/frame_host/render_frame_host_impl.h"
773+#include "content/public/browser/browser_thread.h"
774+#include "content/public/browser/render_frame_host.h"
775+#include "content/public/browser/render_process_host.h"
776+#include "content/public/browser/render_view_host.h"
777+#include "content/public/browser/resource_context.h"
778+#include "content/public/common/referrer.h"
779+#include "ipc/ipc_message.h"
780+#include "ipc/ipc_message_macros.h"
781+#include "net/cookies/cookie_monster.h"
782+#include "net/url_request/url_request_context.h"
783+#include "url/gurl.h"
784+
785+#include "shared/common/oxide_messages.h"
786+#include "shared/common/oxide_script_message_handler.h"
787+#include "shared/common/oxide_script_message_request.h"
788+
789+#include "oxide_script_message_impl_browser.h"
790+#include "oxide_script_message_request_impl_browser.h"
791+#include "oxide_script_message_target.h"
792+#include "oxide_web_frame.h"
793+#include "oxide_web_view.h"
794+
795+namespace oxide {
796+
797+bool ResourceDispatcherHostDelegate::ShouldDownloadUrl(const GURL& url,
798+ const GURL& first_party_url,
799+ bool is_content_initiated,
800+ const base::string16& suggested_name,
801+ const bool use_prompt,
802+ const content::Referrer& referrer,
803+ const std::string& mime_type,
804+ int render_process_id,
805+ int render_view_id,
806+ content::ResourceContext* resource_context) {
807+
808+ DispatchDownloadRequest(
809+ url,
810+ first_party_url,
811+ is_content_initiated,
812+ suggested_name,
813+ use_prompt,
814+ referrer,
815+ mime_type,
816+ render_process_id,
817+ render_view_id,
818+ resource_context);
819+
820+ return false;
821+}
822+
823+void ResourceDispatcherHostDelegate::DispatchDownloadRequest(
824+ const GURL& url,
825+ const GURL& first_party_url,
826+ bool is_content_initiated,
827+ const base::string16& suggested_name,
828+ const bool use_prompt,
829+ const content::Referrer& referrer,
830+ const std::string& mime_type,
831+ int render_process_id,
832+ int render_view_id,
833+ content::ResourceContext* resource_context) {
834+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
835+
836+ DownloadRequestParams params;
837+ params.url = url;
838+ params.is_content_initiated = is_content_initiated;
839+ params.suggested_name = suggested_name;
840+ params.use_prompt = use_prompt;
841+ params.referrer = referrer.url;
842+ params.mime_type = mime_type;
843+ params.render_process_id = render_process_id;
844+ params.render_view_id = render_view_id;
845+
846+ BrowserContextIOData* io_data =
847+ BrowserContextIOData::FromResourceContext(resource_context);
848+
849+ if (io_data && io_data->CanAccessCookies(url, first_party_url, false)) {
850+ net::CookieStore* cookie_store =
851+ GetCookieStoreForContext(resource_context);
852+
853+ if (cookie_store) {
854+ net::CookieOptions cookie_options;
855+ cookie_options.set_include_httponly();
856+
857+ cookie_store->GetCookiesWithOptionsAsync(
858+ url, cookie_options,
859+ base::Bind(&ResourceDispatcherHostDelegate::DispatchDownloadRequestWithCookies,
860+ params));
861+ return;
862+ }
863+ }
864+
865+ // Fallback with default with empty cookies
866+ DispatchDownloadRequestWithCookies(params, std::string());
867+}
868+
869+void ResourceDispatcherHostDelegate::DispatchDownloadRequestWithCookies(
870+ const DownloadRequestParams & params,
871+ const std::string& cookies) {
872+ if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
873+ content::BrowserThread::PostTask(
874+ content::BrowserThread::UI,
875+ FROM_HERE,
876+ base::Bind(&ResourceDispatcherHostDelegate::DispatchDownloadRequestWithCookies,
877+ params, cookies));
878+ return;
879+ }
880+ content::RenderViewHost* rvh =
881+ content::RenderViewHost::FromID(
882+ params.render_process_id, params.render_view_id);
883+ if (!rvh) {
884+ LOG(ERROR) << "Invalid or non-existent render_process_id & render_view_id:"
885+ << params.render_process_id << ", " << params.render_view_id
886+ << "during download url delegate dispatch";
887+ return;
888+ }
889+
890+ WebView* webview = WebView::FromRenderViewHost(rvh);
891+ if (!webview) {
892+ return;
893+ }
894+ webview->DownloadRequested(
895+ params.url,
896+ params.mime_type,
897+ params.use_prompt,
898+ params.suggested_name,
899+ cookies,
900+ params.referrer.spec());
901+}
902+
903+net::CookieStore* ResourceDispatcherHostDelegate::GetCookieStoreForContext(
904+ content::ResourceContext* resource_context) {
905+ return resource_context && resource_context->GetRequestContext()
906+ ? resource_context->GetRequestContext()->cookie_store()
907+ : NULL;
908+}
909+
910+} // namespace oxide
911
912=== added file 'shared/browser/oxide_resource_dispatcher_host_delegate.h'
913--- shared/browser/oxide_resource_dispatcher_host_delegate.h 1970-01-01 00:00:00 +0000
914+++ shared/browser/oxide_resource_dispatcher_host_delegate.h 2014-06-27 18:46:24 +0000
915@@ -0,0 +1,92 @@
916+// vim:expandtab:shiftwidth=2:tabstop=2:
917+// Copyright (C) 2014 Canonical Ltd.
918+
919+// This library is free software; you can redistribute it and/or
920+// modify it under the terms of the GNU Lesser General Public
921+// License as published by the Free Software Foundation; either
922+// version 2.1 of the License, or (at your option) any later version.
923+
924+// This library is distributed in the hope that it will be useful,
925+// but WITHOUT ANY WARRANTY; without even the implied warranty of
926+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
927+// Lesser General Public License for more details.
928+
929+// You should have received a copy of the GNU Lesser General Public
930+// License along with this library; if not, write to the Free Software
931+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
932+
933+#ifndef _OXIDE_SHARED_BROWSER_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
934+#define _OXIDE_SHARED_BROWSER_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
935+
936+#include "base/basictypes.h"
937+#include "base/compiler_specific.h"
938+#include "base/memory/ref_counted.h"
939+#include "content/public/browser/content_browser_client.h"
940+#include "content/public/browser/resource_dispatcher_host_delegate.h"
941+
942+namespace content {
943+class ResourceContext;
944+struct Referrer;
945+}
946+
947+namespace net {
948+class URLRequest;
949+class CookieStore;
950+}
951+
952+namespace oxide {
953+
954+class ResourceDispatcherHostDelegate :
955+ public content::ResourceDispatcherHostDelegate {
956+ public:
957+ ~ResourceDispatcherHostDelegate() {}
958+
959+ virtual bool ShouldDownloadUrl(
960+ const GURL& url,
961+ const GURL& first_party_url,
962+ bool is_content_initiated,
963+ const base::string16& suggested_name,
964+ const bool use_prompt,
965+ const content::Referrer& referrer,
966+ const std::string& mime_type,
967+ int render_process_id,
968+ int render_view_id,
969+ content::ResourceContext* resource_context) FINAL;
970+
971+ private:
972+
973+ struct DownloadRequestParams {
974+ GURL url;
975+ bool is_content_initiated;
976+ base::string16 suggested_name;
977+ bool use_prompt;
978+ GURL referrer;
979+ std::string mime_type;
980+ int render_process_id;
981+ int render_view_id;
982+ };
983+
984+ void DispatchDownloadRequest(
985+ const GURL& url,
986+ const GURL& first_party_url,
987+ bool is_content_initiated,
988+ const base::string16& suggested_name,
989+ const bool use_prompt,
990+ const content::Referrer& referrer,
991+ const std::string& mime_type,
992+ int render_process_id,
993+ int render_view_id,
994+ content::ResourceContext* resource_context);
995+
996+ static void DispatchDownloadRequestWithCookies(
997+ const DownloadRequestParams & params,
998+ const std::string& cookies);
999+
1000+ net::CookieStore* GetCookieStoreForContext(
1001+ content::ResourceContext* resource_context);
1002+};
1003+
1004+} // namespace oxide
1005+
1006+#endif // OXIDE_SHARED_BROWSER_RESOURCE_DISPATCHER_HOST_DELEGATE
1007+
1008
1009=== modified file 'shared/browser/oxide_web_view.cc'
1010--- shared/browser/oxide_web_view.cc 2014-06-24 14:54:27 +0000
1011+++ shared/browser/oxide_web_view.cc 2014-06-27 18:46:24 +0000
1012@@ -577,6 +577,13 @@
1013 return NULL;
1014 }
1015
1016+void WebView::OnDownloadRequested(const GURL& url,
1017+ const std::string& mimeType,
1018+ const bool shouldPrompt,
1019+ const base::string16& suggestedFilename,
1020+ const std::string& cookies,
1021+ const std::string& referrer) {}
1022+
1023 WebView::WebView()
1024 : web_contents_helper_(NULL),
1025 initial_preferences_(NULL),
1026@@ -1059,4 +1066,15 @@
1027 }
1028 }
1029
1030+void WebView::DownloadRequested(
1031+ const GURL& url,
1032+ const std::string& mimeType,
1033+ const bool shouldPrompt,
1034+ const base::string16& suggestedFilename,
1035+ const std::string& cookies,
1036+ const std::string& referrer) {
1037+ OnDownloadRequested(url, mimeType, shouldPrompt,
1038+ suggestedFilename, cookies, referrer);
1039+}
1040+
1041 } // namespace oxide
1042
1043=== modified file 'shared/browser/oxide_web_view.h'
1044--- shared/browser/oxide_web_view.h 2014-06-24 14:54:27 +0000
1045+++ shared/browser/oxide_web_view.h 2014-06-27 18:46:24 +0000
1046@@ -177,6 +177,14 @@
1047 void GotNewCompositorFrameMetadata(
1048 const cc::CompositorFrameMetadata& metadata);
1049
1050+ void DownloadRequested(
1051+ const GURL& url,
1052+ const std::string& mimeType,
1053+ const bool shouldPrompt,
1054+ const base::string16& suggestedFilename,
1055+ const std::string& cookies,
1056+ const std::string& referrer) FINAL;
1057+
1058 protected:
1059 WebView();
1060
1061@@ -334,6 +342,14 @@
1062 virtual WebView* CreateNewWebView(const gfx::Rect& initial_pos,
1063 WindowOpenDisposition disposition);
1064
1065+ virtual void OnDownloadRequested(
1066+ const GURL& url,
1067+ const std::string& mimeType,
1068+ const bool shouldPrompt,
1069+ const base::string16& suggestedFilename,
1070+ const std::string& cookies,
1071+ const std::string& referrer);
1072+
1073 scoped_ptr<content::WebContentsImpl> web_contents_;
1074 WebViewContentsHelper* web_contents_helper_;
1075
1076
1077=== modified file 'shared/shared.gyp'
1078--- shared/shared.gyp 2014-06-24 15:13:15 +0000
1079+++ shared/shared.gyp 2014-06-27 18:46:24 +0000
1080@@ -276,6 +276,8 @@
1081 'browser/oxide_render_widget_host_view.h',
1082 'browser/oxide_render_widget_host_view_factory.cc',
1083 'browser/oxide_render_widget_host_view_factory.h',
1084+ 'browser/oxide_resource_dispatcher_host_delegate.cc',
1085+ 'browser/oxide_resource_dispatcher_host_delegate.h',
1086 'browser/oxide_script_message_dispatcher_browser.cc',
1087 'browser/oxide_script_message_dispatcher_browser.h',
1088 'browser/oxide_script_message_impl_browser.cc',

Subscribers

People subscribed via source and target branches