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_contents_client_bridge_base.h"
10 #include "android_webview/browser/aw_contents_io_thread_client.h"
11 #include "android_webview/browser/aw_cookie_access_policy.h"
12 #include "android_webview/browser/aw_quota_permission_context.h"
13 #include "android_webview/browser/aw_web_preferences_populater.h"
14 #include "android_webview/browser/jni_dependency_factory.h"
15 #include "android_webview/browser/net_disk_cache_remover.h"
16 #include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"
17 #include "android_webview/common/render_view_messages.h"
18 #include "android_webview/common/url_constants.h"
19 #include "base/base_paths_android.h"
20 #include "base/path_service.h"
21 #include "components/cdm/browser/cdm_message_filter_android.h"
22 #include "content/public/browser/access_token_store.h"
23 #include "content/public/browser/browser_message_filter.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/child_process_security_policy.h"
26 #include "content/public/browser/render_process_host.h"
27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/common/url_constants.h"
30 #include "grit/ui_resources.h"
31 #include "net/android/network_library.h"
32 #include "net/ssl/ssl_cert_request_info.h"
33 #include "net/ssl/ssl_info.h"
34 #include "ui/base/l10n/l10n_util_android.h"
35 #include "ui/base/resource/resource_bundle.h"
36 #include "webkit/common/webpreferences.h"
38 using content::BrowserThread;
40 namespace android_webview {
43 // TODO(sgurun) move this to its own file.
44 // This class filters out incoming aw_contents related IPC messages for the
45 // renderer process on the IPC thread.
46 class AwContentsMessageFilter : public content::BrowserMessageFilter {
48 explicit AwContentsMessageFilter(int process_id);
50 // BrowserMessageFilter methods.
51 virtual void OverrideThreadForMessage(
52 const IPC::Message& message,
53 BrowserThread::ID* thread) OVERRIDE;
54 virtual bool OnMessageReceived(
55 const IPC::Message& message,
56 bool* message_was_ok) OVERRIDE;
58 void OnShouldOverrideUrlLoading(int routing_id,
59 const base::string16& url,
60 bool* ignore_navigation);
61 void OnSubFrameCreated(int parent_render_frame_id, int child_render_frame_id);
64 virtual ~AwContentsMessageFilter();
68 DISALLOW_COPY_AND_ASSIGN(AwContentsMessageFilter);
71 AwContentsMessageFilter::AwContentsMessageFilter(int process_id)
72 : BrowserMessageFilter(AndroidWebViewMsgStart),
73 process_id_(process_id) {
76 AwContentsMessageFilter::~AwContentsMessageFilter() {
79 void AwContentsMessageFilter::OverrideThreadForMessage(
80 const IPC::Message& message, BrowserThread::ID* thread) {
81 if (message.type() == AwViewHostMsg_ShouldOverrideUrlLoading::ID) {
82 *thread = BrowserThread::UI;
86 bool AwContentsMessageFilter::OnMessageReceived(const IPC::Message& message,
87 bool* message_was_ok) {
89 IPC_BEGIN_MESSAGE_MAP_EX(AwContentsMessageFilter, message, *message_was_ok)
90 IPC_MESSAGE_HANDLER(AwViewHostMsg_ShouldOverrideUrlLoading,
91 OnShouldOverrideUrlLoading)
92 IPC_MESSAGE_HANDLER(AwViewHostMsg_SubFrameCreated, OnSubFrameCreated)
93 IPC_MESSAGE_UNHANDLED(handled = false)
98 void AwContentsMessageFilter::OnShouldOverrideUrlLoading(
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);
107 *ignore_navigation = client->ShouldOverrideUrlLoading(url);
109 LOG(WARNING) << "Failed to find the associated render view host for 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 {
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 { }
136 virtual ~AwAccessTokenStore() { }
138 DISALLOW_COPY_AND_ASSIGN(AwAccessTokenStore);
143 std::string AwContentBrowserClient::GetAcceptLangsImpl() {
144 // Start with the currnet locale.
145 std::string langs = l10n_util::GetDefaultLocale();
147 // If we're not en-US, add in en-US which will be
148 // used with a lower q-value.
149 if (StringToLowerASCII(langs) != "en-us") {
155 AwBrowserContext* AwContentBrowserClient::GetAwBrowserContext() {
156 return AwBrowserContext::GetDefault();
159 AwContentBrowserClient::AwContentBrowserClient(
160 JniDependencyFactory* native_factory)
161 : native_factory_(native_factory) {
162 base::FilePath user_data_dir;
163 if (!PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) {
164 NOTREACHED() << "Failed to get app data directory for Android WebView";
166 browser_context_.reset(
167 new AwBrowserContext(user_data_dir, native_factory_));
170 AwContentBrowserClient::~AwContentBrowserClient() {
173 void AwContentBrowserClient::AddCertificate(net::URLRequest* request,
174 net::CertificateMimeType cert_type,
175 const void* cert_data,
177 int render_process_id,
178 int render_view_id) {
180 net::android::StoreCertificate(cert_type, cert_data, cert_size);
183 content::BrowserMainParts* AwContentBrowserClient::CreateBrowserMainParts(
184 const content::MainFunctionParams& parameters) {
185 return new AwBrowserMainParts(browser_context_.get());
188 content::WebContentsViewDelegate*
189 AwContentBrowserClient::GetWebContentsViewDelegate(
190 content::WebContents* web_contents) {
191 return native_factory_->CreateViewDelegate(web_contents);
194 void AwContentBrowserClient::RenderProcessWillLaunch(
195 content::RenderProcessHost* host) {
196 // If WebView becomes multi-process capable, this may be insecure.
197 // More benefit can be derived from the ChildProcessSecurotyPolicy by
198 // deferring the GrantScheme calls until we know that a given child process
199 // really does need that priviledge. Check here to ensure we rethink this
200 // when the time comes. See crbug.com/156062.
201 CHECK(content::RenderProcessHost::run_renderer_in_process());
203 // Grant content: and file: scheme to the whole process, since we impose
204 // per-view access checks.
205 content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
206 host->GetID(), android_webview::kContentScheme);
207 content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
208 host->GetID(), content::kFileScheme);
210 host->AddFilter(new AwContentsMessageFilter(host->GetID()));
211 host->AddFilter(new cdm::CdmMessageFilterAndroid());
214 net::URLRequestContextGetter* AwContentBrowserClient::CreateRequestContext(
215 content::BrowserContext* browser_context,
216 content::ProtocolHandlerMap* protocol_handlers,
217 content::ProtocolHandlerScopedVector protocol_interceptors) {
218 DCHECK(browser_context_.get() == browser_context);
219 // TODO(mkosiba,kinuko): protocol_interceptors should be hooked up in the
220 // downstream. (crbug.com/350286)
221 return browser_context_->CreateRequestContext(protocol_handlers);
224 net::URLRequestContextGetter*
225 AwContentBrowserClient::CreateRequestContextForStoragePartition(
226 content::BrowserContext* browser_context,
227 const base::FilePath& partition_path,
229 content::ProtocolHandlerMap* protocol_handlers,
230 content::ProtocolHandlerScopedVector protocol_interceptors) {
231 DCHECK(browser_context_.get() == browser_context);
232 return browser_context_->CreateRequestContextForStoragePartition(
233 partition_path, in_memory, protocol_handlers);
236 std::string AwContentBrowserClient::GetCanonicalEncodingNameByAliasName(
237 const std::string& alias_name) {
241 void AwContentBrowserClient::AppendExtraCommandLineSwitches(
242 base::CommandLine* command_line,
243 int child_process_id) {
244 NOTREACHED() << "Android WebView does not support multi-process yet";
247 std::string AwContentBrowserClient::GetApplicationLocale() {
248 return l10n_util::GetDefaultLocale();
251 std::string AwContentBrowserClient::GetAcceptLangs(
252 content::BrowserContext* context) {
253 return GetAcceptLangsImpl();
256 gfx::ImageSkia* AwContentBrowserClient::GetDefaultFavicon() {
257 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
258 // TODO(boliu): Bundle our own default favicon?
259 return rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
262 bool AwContentBrowserClient::AllowAppCache(const GURL& manifest_url,
263 const GURL& first_party,
264 content::ResourceContext* context) {
265 // WebView doesn't have a per-site policy for locally stored data,
266 // instead AppCache can be disabled for individual WebViews.
271 bool AwContentBrowserClient::AllowGetCookie(const GURL& url,
272 const GURL& first_party,
273 const net::CookieList& cookie_list,
274 content::ResourceContext* context,
275 int render_process_id,
276 int render_frame_id) {
277 return AwCookieAccessPolicy::GetInstance()->AllowGetCookie(url,
285 bool AwContentBrowserClient::AllowSetCookie(const GURL& url,
286 const GURL& first_party,
287 const std::string& cookie_line,
288 content::ResourceContext* context,
289 int render_process_id,
291 net::CookieOptions* options) {
292 return AwCookieAccessPolicy::GetInstance()->AllowSetCookie(url,
301 bool AwContentBrowserClient::AllowWorkerDatabase(
303 const base::string16& name,
304 const base::string16& display_name,
305 unsigned long estimated_size,
306 content::ResourceContext* context,
307 const std::vector<std::pair<int, int> >& render_frames) {
308 // Android WebView does not yet support web workers.
312 bool AwContentBrowserClient::AllowWorkerFileSystem(
314 content::ResourceContext* context,
315 const std::vector<std::pair<int, int> >& render_frames) {
316 // Android WebView does not yet support web workers.
320 bool AwContentBrowserClient::AllowWorkerIndexedDB(
322 const base::string16& name,
323 content::ResourceContext* context,
324 const std::vector<std::pair<int, int> >& render_frames) {
325 // Android WebView does not yet support web workers.
329 content::QuotaPermissionContext*
330 AwContentBrowserClient::CreateQuotaPermissionContext() {
331 return new AwQuotaPermissionContext;
334 void AwContentBrowserClient::AllowCertificateError(
335 int render_process_id,
338 const net::SSLInfo& ssl_info,
339 const GURL& request_url,
340 ResourceType::Type resource_type,
342 bool strict_enforcement,
343 const base::Callback<void(bool)>& callback,
344 content::CertificateRequestResultType* result) {
345 AwContentsClientBridgeBase* client =
346 AwContentsClientBridgeBase::FromID(render_process_id, render_frame_id);
347 bool cancel_request = true;
349 client->AllowCertificateError(cert_error,
355 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
358 void AwContentBrowserClient::SelectClientCertificate(
359 int render_process_id,
361 const net::HttpNetworkSession* network_session,
362 net::SSLCertRequestInfo* cert_request_info,
363 const base::Callback<void(net::X509Certificate*)>& callback) {
364 AwContentsClientBridgeBase* client =
365 AwContentsClientBridgeBase::FromID(render_process_id, render_frame_id);
367 client->SelectClientCertificate(cert_request_info, callback);
373 blink::WebNotificationPresenter::Permission
374 AwContentBrowserClient::CheckDesktopNotificationPermission(
375 const GURL& source_url,
376 content::ResourceContext* context,
377 int render_process_id) {
378 // Android WebView does not support notifications, so return Denied here.
379 return blink::WebNotificationPresenter::PermissionDenied;
382 void AwContentBrowserClient::ShowDesktopNotification(
383 const content::ShowDesktopNotificationHostMsgParams& params,
384 content::RenderFrameHost* render_frame_host,
385 content::DesktopNotificationDelegate* delegate,
386 base::Closure* cancel_callback) {
387 NOTREACHED() << "Android WebView does not support desktop notifications.";
390 bool AwContentBrowserClient::CanCreateWindow(
391 const GURL& opener_url,
392 const GURL& opener_top_level_frame_url,
393 const GURL& source_origin,
394 WindowContainerType container_type,
395 const GURL& target_url,
396 const content::Referrer& referrer,
397 WindowOpenDisposition disposition,
398 const blink::WebWindowFeatures& features,
400 bool opener_suppressed,
401 content::ResourceContext* context,
402 int render_process_id,
405 bool* no_javascript_access) {
406 // We unconditionally allow popup windows at this stage and will give
407 // the embedder the opporunity to handle displaying of the popup in
408 // WebContentsDelegate::AddContents (via the
409 // AwContentsClient.onCreateWindow callback).
410 // Note that if the embedder has blocked support for creating popup
411 // windows through AwSettings, then we won't get to this point as
412 // the popup creation will have been blocked at the WebKit level.
413 if (no_javascript_access) {
414 *no_javascript_access = false;
419 std::string AwContentBrowserClient::GetWorkerProcessTitle(const GURL& url,
420 content::ResourceContext* context) {
421 NOTREACHED() << "Android WebView does not yet support web workers.";
422 return std::string();
426 void AwContentBrowserClient::ResourceDispatcherHostCreated() {
427 AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated();
430 net::NetLog* AwContentBrowserClient::GetNetLog() {
431 // TODO(boliu): Implement AwNetLog.
435 content::AccessTokenStore* AwContentBrowserClient::CreateAccessTokenStore() {
436 return new AwAccessTokenStore();
439 bool AwContentBrowserClient::IsFastShutdownPossible() {
440 NOTREACHED() << "Android WebView is single process, so IsFastShutdownPossible"
441 << " should never be called";
445 void AwContentBrowserClient::UpdateInspectorSetting(
446 content::RenderViewHost* rvh,
447 const std::string& key,
448 const std::string& value) {
449 // TODO(boliu): Implement persisting inspector settings.
453 void AwContentBrowserClient::ClearCache(content::RenderViewHost* rvh) {
454 RemoveHttpDiskCache(rvh->GetProcess()->GetBrowserContext(),
455 rvh->GetProcess()->GetID());
458 void AwContentBrowserClient::ClearCookies(content::RenderViewHost* rvh) {
459 // TODO(boliu): Implement.
463 base::FilePath AwContentBrowserClient::GetDefaultDownloadDirectory() {
464 // Android WebView does not currently use the Chromium downloads system.
465 // Download requests are cancelled immedately when recognized; see
466 // AwResourceDispatcherHost::CreateResourceHandlerForDownload. However the
467 // download system still tries to start up and calls this before recognizing
468 // the request has been cancelled.
469 return base::FilePath();
472 std::string AwContentBrowserClient::GetDefaultDownloadName() {
473 NOTREACHED() << "Android WebView does not use chromium downloads";
474 return std::string();
477 void AwContentBrowserClient::DidCreatePpapiPlugin(
478 content::BrowserPpapiHost* browser_host) {
479 NOTREACHED() << "Android WebView does not support plugins";
482 bool AwContentBrowserClient::AllowPepperSocketAPI(
483 content::BrowserContext* browser_context,
486 const content::SocketPermissionRequest* params) {
487 NOTREACHED() << "Android WebView does not support plugins";
491 void AwContentBrowserClient::OverrideWebkitPrefs(content::RenderViewHost* rvh,
493 WebPreferences* web_prefs) {
494 if (!preferences_populater_.get()) {
495 preferences_populater_ = make_scoped_ptr(native_factory_->
496 CreateWebPreferencesPopulater());
498 preferences_populater_->PopulateFor(
499 content::WebContents::FromRenderViewHost(rvh), web_prefs);
502 #if defined(VIDEO_HOLE)
503 content::ExternalVideoSurfaceContainer*
504 AwContentBrowserClient::OverrideCreateExternalVideoSurfaceContainer(
505 content::WebContents* web_contents) {
506 return native_factory_->CreateExternalVideoSurfaceContainer(web_contents);
510 } // namespace android_webview