Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / android_webview / browser / aw_content_browser_client.cc
blob15cd608aae8662934cc7a9a47713c76a1c5c2cfc
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.
5 #include "android_webview/browser/aw_content_browser_client.h"
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 "net/android/network_library.h"
33 #include "net/ssl/ssl_cert_request_info.h"
34 #include "net/ssl/ssl_info.h"
35 #include "ui/base/l10n/l10n_util_android.h"
36 #include "ui/base/resource/resource_bundle.h"
37 #include "ui/resources/grit/ui_resources.h"
39 using content::BrowserThread;
40 using content::ResourceType;
42 namespace android_webview {
43 namespace {
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);
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;
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);
64 private:
65 virtual ~AwContentsMessageFilter();
67 int process_id_;
69 DISALLOW_COPY_AND_ASSIGN(AwContentsMessageFilter);
72 AwContentsMessageFilter::AwContentsMessageFilter(int process_id)
73 : BrowserMessageFilter(AndroidWebViewMsgStart),
74 process_id_(process_id) {
77 AwContentsMessageFilter::~AwContentsMessageFilter() {
80 void AwContentsMessageFilter::OverrideThreadForMessage(
81 const IPC::Message& message, BrowserThread::ID* thread) {
82 if (message.type() == AwViewHostMsg_ShouldOverrideUrlLoading::ID) {
83 *thread = BrowserThread::UI;
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;
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;
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);
120 class AwAccessTokenStore : public content::AccessTokenStore {
121 public:
122 AwAccessTokenStore() { }
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);
132 virtual void SaveAccessToken(const GURL& server_url,
133 const base::string16& access_token) OVERRIDE { }
135 private:
136 virtual ~AwAccessTokenStore() { }
138 DISALLOW_COPY_AND_ASSIGN(AwAccessTokenStore);
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);
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);
163 } // namespace
165 std::string AwContentBrowserClient::GetAcceptLangsImpl() {
166 // Start with the currnet locale.
167 std::string langs = l10n_util::GetDefaultLocale();
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";
174 return langs;
177 AwBrowserContext* AwContentBrowserClient::GetAwBrowserContext() {
178 return AwBrowserContext::GetDefault();
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";
188 browser_context_.reset(
189 new AwBrowserContext(user_data_dir, native_factory_));
192 AwContentBrowserClient::~AwContentBrowserClient() {
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);
204 content::BrowserMainParts* AwContentBrowserClient::CreateBrowserMainParts(
205 const content::MainFunctionParams& parameters) {
206 return new AwBrowserMainParts(browser_context_.get());
209 content::WebContentsViewDelegate*
210 AwContentBrowserClient::GetWebContentsViewDelegate(
211 content::WebContents* web_contents) {
212 return native_factory_->CreateViewDelegate(web_contents);
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());
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);
231 host->AddFilter(new AwContentsMessageFilter(host->GetID()));
232 host->AddFilter(new cdm::CdmMessageFilterAndroid());
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());
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());
259 std::string AwContentBrowserClient::GetCanonicalEncodingNameByAliasName(
260 const std::string& alias_name) {
261 return alias_name;
264 void AwContentBrowserClient::AppendExtraCommandLineSwitches(
265 base::CommandLine* command_line,
266 int child_process_id) {
267 NOTREACHED() << "Android WebView does not support multi-process yet";
270 std::string AwContentBrowserClient::GetApplicationLocale() {
271 return l10n_util::GetDefaultLocale();
274 std::string AwContentBrowserClient::GetAcceptLangs(
275 content::BrowserContext* context) {
276 return GetAcceptLangsImpl();
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);
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;
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);
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);
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;
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);
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;
353 content::QuotaPermissionContext*
354 AwContentBrowserClient::CreateQuotaPermissionContext() {
355 return new AwQuotaPermissionContext;
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;
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);
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;
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.";
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;
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);
439 delegate->RequestGeolocationPermission(origin, result_callback);
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);
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;
470 if (cancel_callback) {
471 *cancel_callback = base::Bind(
472 CancelProtectedMediaIdentifierPermissionRequests,
473 render_process_id, render_view_id, origin);
475 delegate->RequestProtectedMediaIdentifierPermission(origin, result_callback);
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;
503 return true;
506 void AwContentBrowserClient::ResourceDispatcherHostCreated() {
507 AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated();
510 net::NetLog* AwContentBrowserClient::GetNetLog() {
511 // TODO(boliu): Implement AwNetLog.
512 return NULL;
515 content::AccessTokenStore* AwContentBrowserClient::CreateAccessTokenStore() {
516 return new AwAccessTokenStore();
519 bool AwContentBrowserClient::IsFastShutdownPossible() {
520 NOTREACHED() << "Android WebView is single process, so IsFastShutdownPossible"
521 << " should never be called";
522 return false;
525 void AwContentBrowserClient::ClearCache(content::RenderViewHost* rvh) {
526 RemoveHttpDiskCache(rvh->GetProcess()->GetBrowserContext(),
527 rvh->GetProcess()->GetID());
530 void AwContentBrowserClient::ClearCookies(content::RenderViewHost* rvh) {
531 // TODO(boliu): Implement.
532 NOTIMPLEMENTED();
535 base::FilePath AwContentBrowserClient::GetDefaultDownloadDirectory() {
536 // Android WebView does not currently use the Chromium downloads system.
537 // Download requests are cancelled immedately when recognized; see
538 // AwResourceDispatcherHost::CreateResourceHandlerForDownload. However the
539 // download system still tries to start up and calls this before recognizing
540 // the request has been cancelled.
541 return base::FilePath();
544 std::string AwContentBrowserClient::GetDefaultDownloadName() {
545 NOTREACHED() << "Android WebView does not use chromium downloads";
546 return std::string();
549 void AwContentBrowserClient::DidCreatePpapiPlugin(
550 content::BrowserPpapiHost* browser_host) {
551 NOTREACHED() << "Android WebView does not support plugins";
554 bool AwContentBrowserClient::AllowPepperSocketAPI(
555 content::BrowserContext* browser_context,
556 const GURL& url,
557 bool private_api,
558 const content::SocketPermissionRequest* params) {
559 NOTREACHED() << "Android WebView does not support plugins";
560 return false;
563 void AwContentBrowserClient::OverrideWebkitPrefs(
564 content::RenderViewHost* rvh,
565 const GURL& url,
566 content::WebPreferences* web_prefs) {
567 if (!preferences_populater_.get()) {
568 preferences_populater_ = make_scoped_ptr(native_factory_->
569 CreateWebPreferencesPopulater());
571 preferences_populater_->PopulateFor(
572 content::WebContents::FromRenderViewHost(rvh), web_prefs);
575 #if defined(VIDEO_HOLE)
576 content::ExternalVideoSurfaceContainer*
577 AwContentBrowserClient::OverrideCreateExternalVideoSurfaceContainer(
578 content::WebContents* web_contents) {
579 return native_factory_->CreateExternalVideoSurfaceContainer(web_contents);
581 #endif
583 } // namespace android_webview