Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / android_webview / browser / aw_content_browser_client.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "android_webview/browser/aw_content_browser_client.h"
6
7 #include "android_webview/browser/aw_browser_context.h"
8 #include "android_webview/browser/aw_browser_main_parts.h"
9 #include "android_webview/browser/aw_browser_permission_request_delegate.h"
10 #include "android_webview/browser/aw_contents_client_bridge_base.h"
11 #include "android_webview/browser/aw_contents_io_thread_client.h"
12 #include "android_webview/browser/aw_cookie_access_policy.h"
13 #include "android_webview/browser/aw_quota_permission_context.h"
14 #include "android_webview/browser/aw_web_preferences_populater.h"
15 #include "android_webview/browser/jni_dependency_factory.h"
16 #include "android_webview/browser/net_disk_cache_remover.h"
17 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"
18 #include "android_webview/common/render_view_messages.h"
19 #include "android_webview/common/url_constants.h"
20 #include "base/base_paths_android.h"
21 #include "base/path_service.h"
22 #include "components/cdm/browser/cdm_message_filter_android.h"
23 #include "content/public/browser/access_token_store.h"
24 #include "content/public/browser/browser_message_filter.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/child_process_security_policy.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/browser/render_view_host.h"
29 #include "content/public/browser/web_contents.h"
30 #include "content/public/common/url_constants.h"
31 #include "content/public/common/web_preferences.h"
32 #include "grit/ui_resources.h"
33 #include "net/android/network_library.h"
34 #include "net/ssl/ssl_cert_request_info.h"
35 #include "net/ssl/ssl_info.h"
36 #include "ui/base/l10n/l10n_util_android.h"
37 #include "ui/base/resource/resource_bundle.h"
38
39 using content::BrowserThread;
40 using content::ResourceType;
41
42 namespace android_webview {
43 namespace {
44
45 // TODO(sgurun) move this to its own file.
46 // This class filters out incoming aw_contents related IPC messages for the
47 // renderer process on the IPC thread.
48 class AwContentsMessageFilter : public content::BrowserMessageFilter {
49 public:
50   explicit AwContentsMessageFilter(int process_id);
51
52   // BrowserMessageFilter methods.
53   virtual void OverrideThreadForMessage(
54       const IPC::Message& message,
55       BrowserThread::ID* thread) OVERRIDE;
56   virtual bool OnMessageReceived(
57       const IPC::Message& message) OVERRIDE;
58
59   void OnShouldOverrideUrlLoading(int routing_id,
60                                   const base::string16& url,
61                                   bool* ignore_navigation);
62   void OnSubFrameCreated(int parent_render_frame_id, int child_render_frame_id);
63
64 private:
65   virtual ~AwContentsMessageFilter();
66
67   int process_id_;
68
69   DISALLOW_COPY_AND_ASSIGN(AwContentsMessageFilter);
70 };
71
72 AwContentsMessageFilter::AwContentsMessageFilter(int process_id)
73     : BrowserMessageFilter(AndroidWebViewMsgStart),
74       process_id_(process_id) {
75 }
76
77 AwContentsMessageFilter::~AwContentsMessageFilter() {
78 }
79
80 void AwContentsMessageFilter::OverrideThreadForMessage(
81     const IPC::Message& message, BrowserThread::ID* thread) {
82   if (message.type() == AwViewHostMsg_ShouldOverrideUrlLoading::ID) {
83     *thread = BrowserThread::UI;
84   }
85 }
86
87 bool AwContentsMessageFilter::OnMessageReceived(const IPC::Message& message) {
88   bool handled = true;
89   IPC_BEGIN_MESSAGE_MAP(AwContentsMessageFilter, message)
90     IPC_MESSAGE_HANDLER(AwViewHostMsg_ShouldOverrideUrlLoading,
91                         OnShouldOverrideUrlLoading)
92     IPC_MESSAGE_HANDLER(AwViewHostMsg_SubFrameCreated, OnSubFrameCreated)
93     IPC_MESSAGE_UNHANDLED(handled = false)
94   IPC_END_MESSAGE_MAP()
95   return handled;
96 }
97
98 void AwContentsMessageFilter::OnShouldOverrideUrlLoading(
99     int render_frame_id,
100     const base::string16& url,
101     bool* ignore_navigation) {
102   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
103   *ignore_navigation = false;
104   AwContentsClientBridgeBase* client =
105       AwContentsClientBridgeBase::FromID(process_id_, render_frame_id);
106   if (client) {
107     *ignore_navigation = client->ShouldOverrideUrlLoading(url);
108   } else {
109     LOG(WARNING) << "Failed to find the associated render view host for url: "
110                  << url;
111   }
112 }
113
114 void AwContentsMessageFilter::OnSubFrameCreated(int parent_render_frame_id,
115                                                 int child_render_frame_id) {
116   AwContentsIoThreadClient::SubFrameCreated(
117       process_id_, parent_render_frame_id, child_render_frame_id);
118 }
119
120 class AwAccessTokenStore : public content::AccessTokenStore {
121  public:
122   AwAccessTokenStore() { }
123
124   // content::AccessTokenStore implementation
125   virtual void LoadAccessTokens(
126       const LoadAccessTokensCallbackType& request) OVERRIDE {
127     AccessTokenStore::AccessTokenSet access_token_set;
128     // AccessTokenSet and net::URLRequestContextGetter not used on Android,
129     // but Run needs to be called to finish the geolocation setup.
130     request.Run(access_token_set, NULL);
131   }
132   virtual void SaveAccessToken(const GURL& server_url,
133                                const base::string16& access_token) OVERRIDE { }
134
135  private:
136   virtual ~AwAccessTokenStore() { }
137
138   DISALLOW_COPY_AND_ASSIGN(AwAccessTokenStore);
139 };
140
141 void CancelProtectedMediaIdentifierPermissionRequests(
142     int render_process_id,
143     int render_view_id,
144     const GURL& origin) {
145   AwBrowserPermissionRequestDelegate* delegate =
146       AwBrowserPermissionRequestDelegate::FromID(render_process_id,
147                                                  render_view_id);
148   if (delegate)
149     delegate->CancelProtectedMediaIdentifierPermissionRequests(origin);
150 }
151
152 void CancelGeolocationPermissionRequests(
153     int render_process_id,
154     int render_view_id,
155     const GURL& origin) {
156   AwBrowserPermissionRequestDelegate* delegate =
157       AwBrowserPermissionRequestDelegate::FromID(render_process_id,
158                                                  render_view_id);
159   if (delegate)
160     delegate->CancelGeolocationPermissionRequests(origin);
161 }
162
163 }  // namespace
164
165 std::string AwContentBrowserClient::GetAcceptLangsImpl() {
166   // Start with the currnet locale.
167   std::string langs = l10n_util::GetDefaultLocale();
168
169   // If we're not en-US, add in en-US which will be
170   // used with a lower q-value.
171   if (base::StringToLowerASCII(langs) != "en-us") {
172     langs += ",en-US";
173   }
174   return langs;
175 }
176
177 AwBrowserContext* AwContentBrowserClient::GetAwBrowserContext() {
178   return AwBrowserContext::GetDefault();
179 }
180
181 AwContentBrowserClient::AwContentBrowserClient(
182     JniDependencyFactory* native_factory)
183     : native_factory_(native_factory) {
184   base::FilePath user_data_dir;
185   if (!PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) {
186     NOTREACHED() << "Failed to get app data directory for Android WebView";
187   }
188   browser_context_.reset(
189       new AwBrowserContext(user_data_dir, native_factory_));
190 }
191
192 AwContentBrowserClient::~AwContentBrowserClient() {
193 }
194
195 void AwContentBrowserClient::AddCertificate(net::CertificateMimeType cert_type,
196                                             const void* cert_data,
197                                             size_t cert_size,
198                                             int render_process_id,
199                                             int render_frame_id) {
200   if (cert_size > 0)
201     net::android::StoreCertificate(cert_type, cert_data, cert_size);
202 }
203
204 content::BrowserMainParts* AwContentBrowserClient::CreateBrowserMainParts(
205     const content::MainFunctionParams& parameters) {
206   return new AwBrowserMainParts(browser_context_.get());
207 }
208
209 content::WebContentsViewDelegate*
210 AwContentBrowserClient::GetWebContentsViewDelegate(
211     content::WebContents* web_contents) {
212   return native_factory_->CreateViewDelegate(web_contents);
213 }
214
215 void AwContentBrowserClient::RenderProcessWillLaunch(
216     content::RenderProcessHost* host) {
217   // If WebView becomes multi-process capable, this may be insecure.
218   // More benefit can be derived from the ChildProcessSecurotyPolicy by
219   // deferring the GrantScheme calls until we know that a given child process
220   // really does need that priviledge. Check here to ensure we rethink this
221   // when the time comes. See crbug.com/156062.
222   CHECK(content::RenderProcessHost::run_renderer_in_process());
223
224   // Grant content: and file: scheme to the whole process, since we impose
225   // per-view access checks.
226   content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
227       host->GetID(), android_webview::kContentScheme);
228   content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
229       host->GetID(), url::kFileScheme);
230
231   host->AddFilter(new AwContentsMessageFilter(host->GetID()));
232   host->AddFilter(new cdm::CdmMessageFilterAndroid());
233 }
234
235 net::URLRequestContextGetter* AwContentBrowserClient::CreateRequestContext(
236     content::BrowserContext* browser_context,
237     content::ProtocolHandlerMap* protocol_handlers,
238     content::URLRequestInterceptorScopedVector request_interceptors) {
239   DCHECK(browser_context_.get() == browser_context);
240   return browser_context_->CreateRequestContext(protocol_handlers,
241                                                 request_interceptors.Pass());
242 }
243
244 net::URLRequestContextGetter*
245 AwContentBrowserClient::CreateRequestContextForStoragePartition(
246     content::BrowserContext* browser_context,
247     const base::FilePath& partition_path,
248     bool in_memory,
249     content::ProtocolHandlerMap* protocol_handlers,
250     content::URLRequestInterceptorScopedVector request_interceptors) {
251   DCHECK(browser_context_.get() == browser_context);
252   // TODO(mkosiba,kinuko): request_interceptors should be hooked up in the
253   // downstream. (crbug.com/350286)
254   return browser_context_->CreateRequestContextForStoragePartition(
255       partition_path, in_memory, protocol_handlers,
256       request_interceptors.Pass());
257 }
258
259 std::string AwContentBrowserClient::GetCanonicalEncodingNameByAliasName(
260     const std::string& alias_name) {
261   return alias_name;
262 }
263
264 void AwContentBrowserClient::AppendExtraCommandLineSwitches(
265     base::CommandLine* command_line,
266     int child_process_id) {
267   NOTREACHED() << "Android WebView does not support multi-process yet";
268 }
269
270 std::string AwContentBrowserClient::GetApplicationLocale() {
271   return l10n_util::GetDefaultLocale();
272 }
273
274 std::string AwContentBrowserClient::GetAcceptLangs(
275     content::BrowserContext* context) {
276   return GetAcceptLangsImpl();
277 }
278
279 const gfx::ImageSkia* AwContentBrowserClient::GetDefaultFavicon() {
280   ResourceBundle& rb = ResourceBundle::GetSharedInstance();
281   // TODO(boliu): Bundle our own default favicon?
282   return rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
283 }
284
285 bool AwContentBrowserClient::AllowAppCache(const GURL& manifest_url,
286                            const GURL& first_party,
287                            content::ResourceContext* context) {
288   // WebView doesn't have a per-site policy for locally stored data,
289   // instead AppCache can be disabled for individual WebViews.
290   return true;
291 }
292
293
294 bool AwContentBrowserClient::AllowGetCookie(const GURL& url,
295                                             const GURL& first_party,
296                                             const net::CookieList& cookie_list,
297                                             content::ResourceContext* context,
298                                             int render_process_id,
299                                             int render_frame_id) {
300   return AwCookieAccessPolicy::GetInstance()->AllowGetCookie(url,
301                                                              first_party,
302                                                              cookie_list,
303                                                              context,
304                                                              render_process_id,
305                                                              render_frame_id);
306 }
307
308 bool AwContentBrowserClient::AllowSetCookie(const GURL& url,
309                                             const GURL& first_party,
310                                             const std::string& cookie_line,
311                                             content::ResourceContext* context,
312                                             int render_process_id,
313                                             int render_frame_id,
314                                             net::CookieOptions* options) {
315   return AwCookieAccessPolicy::GetInstance()->AllowSetCookie(url,
316                                                              first_party,
317                                                              cookie_line,
318                                                              context,
319                                                              render_process_id,
320                                                              render_frame_id,
321                                                              options);
322 }
323
324 bool AwContentBrowserClient::AllowWorkerDatabase(
325     const GURL& url,
326     const base::string16& name,
327     const base::string16& display_name,
328     unsigned long estimated_size,
329     content::ResourceContext* context,
330     const std::vector<std::pair<int, int> >& render_frames) {
331   // Android WebView does not yet support web workers.
332   return false;
333 }
334
335 void AwContentBrowserClient::AllowWorkerFileSystem(
336     const GURL& url,
337     content::ResourceContext* context,
338     const std::vector<std::pair<int, int> >& render_frames,
339     base::Callback<void(bool)> callback) {
340   // Android WebView does not yet support web workers.
341   callback.Run(false);
342 }
343
344 bool AwContentBrowserClient::AllowWorkerIndexedDB(
345     const GURL& url,
346     const base::string16& name,
347     content::ResourceContext* context,
348     const std::vector<std::pair<int, int> >& render_frames) {
349   // Android WebView does not yet support web workers.
350   return false;
351 }
352
353 content::QuotaPermissionContext*
354 AwContentBrowserClient::CreateQuotaPermissionContext() {
355   return new AwQuotaPermissionContext;
356 }
357
358 void AwContentBrowserClient::AllowCertificateError(
359     int render_process_id,
360     int render_frame_id,
361     int cert_error,
362     const net::SSLInfo& ssl_info,
363     const GURL& request_url,
364     ResourceType resource_type,
365     bool overridable,
366     bool strict_enforcement,
367     bool expired_previous_decision,
368     const base::Callback<void(bool)>& callback,
369     content::CertificateRequestResultType* result) {
370   AwContentsClientBridgeBase* client =
371       AwContentsClientBridgeBase::FromID(render_process_id, render_frame_id);
372   bool cancel_request = true;
373   if (client)
374     client->AllowCertificateError(cert_error,
375                                   ssl_info.cert.get(),
376                                   request_url,
377                                   callback,
378                                   &cancel_request);
379   if (cancel_request)
380     *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
381 }
382
383 void AwContentBrowserClient::SelectClientCertificate(
384       int render_process_id,
385       int render_frame_id,
386       const net::HttpNetworkSession* network_session,
387       net::SSLCertRequestInfo* cert_request_info,
388       const base::Callback<void(net::X509Certificate*)>& callback) {
389   AwContentsClientBridgeBase* client =
390       AwContentsClientBridgeBase::FromID(render_process_id, render_frame_id);
391   if (client) {
392     client->SelectClientCertificate(cert_request_info, callback);
393   } else {
394     callback.Run(NULL);
395   }
396 }
397
398 blink::WebNotificationPermission
399     AwContentBrowserClient::CheckDesktopNotificationPermission(
400         const GURL& source_url,
401         content::ResourceContext* context,
402         int render_process_id) {
403   // Android WebView does not support notifications, so return Denied here.
404   return blink::WebNotificationPermissionDenied;
405 }
406
407 void AwContentBrowserClient::ShowDesktopNotification(
408     const content::ShowDesktopNotificationHostMsgParams& params,
409     content::RenderFrameHost* render_frame_host,
410     scoped_ptr<content::DesktopNotificationDelegate> delegate,
411     base::Closure* cancel_callback) {
412   NOTREACHED() << "Android WebView does not support desktop notifications.";
413 }
414
415 void AwContentBrowserClient::RequestGeolocationPermission(
416     content::WebContents* web_contents,
417     int bridge_id,
418     const GURL& requesting_frame,
419     bool user_gesture,
420     base::Callback<void(bool)> result_callback,
421     base::Closure* cancel_callback) {
422   int render_process_id = web_contents->GetRenderProcessHost()->GetID();
423   int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
424   AwBrowserPermissionRequestDelegate* delegate =
425       AwBrowserPermissionRequestDelegate::FromID(render_process_id,
426                                                  render_view_id);
427   if (delegate == NULL) {
428     DVLOG(0) << "Dropping GeolocationPermission request";
429     result_callback.Run(false);
430     return;
431   }
432
433   GURL origin = requesting_frame.GetOrigin();
434   if (cancel_callback) {
435     *cancel_callback = base::Bind(
436         CancelGeolocationPermissionRequests, render_process_id, render_view_id,
437         origin);
438   }
439   delegate->RequestGeolocationPermission(origin, result_callback);
440 }
441
442 void AwContentBrowserClient::RequestMidiSysExPermission(
443     content::WebContents* web_contents,
444     int bridge_id,
445     const GURL& requesting_frame,
446     bool user_gesture,
447     base::Callback<void(bool)> result_callback,
448     base::Closure* cancel_callback) {
449   // TODO(toyoshim): Android WebView is not supported yet.
450   // See http://crbug.com/339767.
451   result_callback.Run(false);
452 }
453
454 void AwContentBrowserClient::RequestProtectedMediaIdentifierPermission(
455     content::WebContents* web_contents,
456     const GURL& origin,
457     base::Callback<void(bool)> result_callback,
458     base::Closure* cancel_callback) {
459   int render_process_id = web_contents->GetRenderProcessHost()->GetID();
460   int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
461   AwBrowserPermissionRequestDelegate* delegate =
462       AwBrowserPermissionRequestDelegate::FromID(render_process_id,
463                                                  render_view_id);
464   if (delegate == NULL) {
465     DVLOG(0) << "Dropping ProtectedMediaIdentifierPermission request";
466     result_callback.Run(false);
467     return;
468   }
469
470   if (cancel_callback) {
471     *cancel_callback = base::Bind(
472         CancelProtectedMediaIdentifierPermissionRequests,
473         render_process_id, render_view_id, origin);
474   }
475   delegate->RequestProtectedMediaIdentifierPermission(origin, result_callback);
476 }
477
478 bool AwContentBrowserClient::CanCreateWindow(
479     const GURL& opener_url,
480     const GURL& opener_top_level_frame_url,
481     const GURL& source_origin,
482     WindowContainerType container_type,
483     const GURL& target_url,
484     const content::Referrer& referrer,
485     WindowOpenDisposition disposition,
486     const blink::WebWindowFeatures& features,
487     bool user_gesture,
488     bool opener_suppressed,
489     content::ResourceContext* context,
490     int render_process_id,
491     int opener_id,
492     bool* no_javascript_access) {
493   // We unconditionally allow popup windows at this stage and will give
494   // the embedder the opporunity to handle displaying of the popup in
495   // WebContentsDelegate::AddContents (via the
496   // AwContentsClient.onCreateWindow callback).
497   // Note that if the embedder has blocked support for creating popup
498   // windows through AwSettings, then we won't get to this point as
499   // the popup creation will have been blocked at the WebKit level.
500   if (no_javascript_access) {
501     *no_javascript_access = false;
502   }
503   return true;
504 }
505
506 std::string AwContentBrowserClient::GetWorkerProcessTitle(const GURL& url,
507                                           content::ResourceContext* context) {
508   NOTREACHED() << "Android WebView does not yet support web workers.";
509   return std::string();
510 }
511
512
513 void AwContentBrowserClient::ResourceDispatcherHostCreated() {
514   AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated();
515 }
516
517 net::NetLog* AwContentBrowserClient::GetNetLog() {
518   // TODO(boliu): Implement AwNetLog.
519   return NULL;
520 }
521
522 content::AccessTokenStore* AwContentBrowserClient::CreateAccessTokenStore() {
523   return new AwAccessTokenStore();
524 }
525
526 bool AwContentBrowserClient::IsFastShutdownPossible() {
527   NOTREACHED() << "Android WebView is single process, so IsFastShutdownPossible"
528                << " should never be called";
529   return false;
530 }
531
532 void AwContentBrowserClient::UpdateInspectorSetting(
533     content::RenderViewHost* rvh,
534     const std::string& key,
535     const std::string& value) {
536   // TODO(boliu): Implement persisting inspector settings.
537   NOTIMPLEMENTED();
538 }
539
540 void AwContentBrowserClient::ClearCache(content::RenderViewHost* rvh) {
541   RemoveHttpDiskCache(rvh->GetProcess()->GetBrowserContext(),
542                       rvh->GetProcess()->GetID());
543 }
544
545 void AwContentBrowserClient::ClearCookies(content::RenderViewHost* rvh) {
546   // TODO(boliu): Implement.
547   NOTIMPLEMENTED();
548 }
549
550 base::FilePath AwContentBrowserClient::GetDefaultDownloadDirectory() {
551   // Android WebView does not currently use the Chromium downloads system.
552   // Download requests are cancelled immedately when recognized; see
553   // AwResourceDispatcherHost::CreateResourceHandlerForDownload. However the
554   // download system still tries to start up and calls this before recognizing
555   // the request has been cancelled.
556   return base::FilePath();
557 }
558
559 std::string AwContentBrowserClient::GetDefaultDownloadName() {
560   NOTREACHED() << "Android WebView does not use chromium downloads";
561   return std::string();
562 }
563
564 void AwContentBrowserClient::DidCreatePpapiPlugin(
565     content::BrowserPpapiHost* browser_host) {
566   NOTREACHED() << "Android WebView does not support plugins";
567 }
568
569 bool AwContentBrowserClient::AllowPepperSocketAPI(
570     content::BrowserContext* browser_context,
571     const GURL& url,
572     bool private_api,
573     const content::SocketPermissionRequest* params) {
574   NOTREACHED() << "Android WebView does not support plugins";
575   return false;
576 }
577
578 void AwContentBrowserClient::OverrideWebkitPrefs(
579     content::RenderViewHost* rvh,
580     const GURL& url,
581     content::WebPreferences* web_prefs) {
582   if (!preferences_populater_.get()) {
583     preferences_populater_ = make_scoped_ptr(native_factory_->
584         CreateWebPreferencesPopulater());
585   }
586   preferences_populater_->PopulateFor(
587       content::WebContents::FromRenderViewHost(rvh), web_prefs);
588 }
589
590 #if defined(VIDEO_HOLE)
591 content::ExternalVideoSurfaceContainer*
592 AwContentBrowserClient::OverrideCreateExternalVideoSurfaceContainer(
593     content::WebContents* web_contents) {
594   return native_factory_->CreateExternalVideoSurfaceContainer(web_contents);
595 }
596 #endif
597
598 }  // namespace android_webview