123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "android_webview/browser/aw_browser_context.h"
- #include <memory>
- #include <string>
- #include <utility>
- #include "android_webview/browser/aw_browser_process.h"
- #include "android_webview/browser/aw_content_browser_client.h"
- #include "android_webview/browser/aw_download_manager_delegate.h"
- #include "android_webview/browser/aw_form_database_service.h"
- #include "android_webview/browser/aw_permission_manager.h"
- #include "android_webview/browser/aw_quota_manager_bridge.h"
- #include "android_webview/browser/aw_resource_context.h"
- #include "android_webview/browser/aw_web_ui_controller_factory.h"
- #include "android_webview/browser/cookie_manager.h"
- #include "android_webview/browser/metrics/aw_metrics_service_client.h"
- #include "android_webview/browser/network_service/net_helpers.h"
- #include "android_webview/browser/safe_browsing/aw_safe_browsing_allowlist_manager.h"
- #include "android_webview/browser_jni_headers/AwBrowserContext_jni.h"
- #include "android_webview/common/aw_features.h"
- #include "android_webview/common/aw_switches.h"
- #include "android_webview/common/crash_reporter/crash_keys.h"
- #include "base/base_paths_posix.h"
- #include "base/bind.h"
- #include "base/command_line.h"
- #include "base/feature_list.h"
- #include "base/files/file_util.h"
- #include "base/path_service.h"
- #include "base/task/single_thread_task_runner.h"
- #include "components/autofill/core/browser/autocomplete_history_manager.h"
- #include "components/autofill/core/common/autofill_prefs.h"
- #include "components/cdm/browser/media_drm_storage_impl.h"
- #include "components/crash/core/common/crash_key.h"
- #include "components/download/public/common/in_progress_download_manager.h"
- #include "components/keyed_service/core/simple_key_map.h"
- #include "components/policy/core/browser/browser_policy_connector_base.h"
- #include "components/policy/core/browser/configuration_policy_pref_store.h"
- #include "components/policy/core/browser/url_blocklist_manager.h"
- #include "components/pref_registry/pref_registry_syncable.h"
- #include "components/prefs/in_memory_pref_store.h"
- #include "components/prefs/json_pref_store.h"
- #include "components/prefs/pref_registry_simple.h"
- #include "components/prefs/pref_service.h"
- #include "components/prefs/pref_service_factory.h"
- #include "components/prefs/segregated_pref_store.h"
- #include "components/profile_metrics/browser_profile_type.h"
- #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
- #include "components/url_formatter/url_fixer.h"
- #include "components/user_prefs/user_prefs.h"
- #include "components/visitedlink/browser/visitedlink_writer.h"
- #include "content/public/browser/browser_task_traits.h"
- #include "content/public/browser/browser_thread.h"
- #include "content/public/browser/download_request_utils.h"
- #include "content/public/browser/ssl_host_state_delegate.h"
- #include "content/public/browser/storage_partition.h"
- #include "content/public/browser/web_contents.h"
- #include "content/public/browser/zoom_level_delegate.h"
- #include "media/mojo/buildflags.h"
- #include "net/http/http_util.h"
- #include "net/proxy_resolution/proxy_config_service_android.h"
- #include "net/proxy_resolution/proxy_resolution_service.h"
- #include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
- #include "services/network/public/mojom/network_context.mojom.h"
- using base::FilePath;
- using content::BrowserThread;
- namespace android_webview {
- namespace {
- const void* const kDownloadManagerDelegateKey = &kDownloadManagerDelegateKey;
- AwBrowserContext* g_browser_context = NULL;
- crash_reporter::CrashKeyString<1> g_web_view_compat_crash_key(
- crash_keys::kWeblayerWebViewCompatMode);
- // Empty method to skip origin security check as DownloadManager will set its
- // own method.
- bool IgnoreOriginSecurityCheck(const GURL& url) {
- return true;
- }
- void MigrateProfileData(base::FilePath cache_path,
- base::FilePath context_storage_path) {
- TRACE_EVENT0("startup", "MigrateProfileData");
- FilePath old_cache_path;
- base::PathService::Get(base::DIR_CACHE, &old_cache_path);
- old_cache_path = old_cache_path.DirName().Append(
- FILE_PATH_LITERAL("org.chromium.android_webview"));
- if (base::PathExists(old_cache_path)) {
- bool success = base::CreateDirectory(cache_path);
- if (success)
- success &= base::Move(old_cache_path, cache_path);
- DCHECK(success);
- }
- base::FilePath old_context_storage_path;
- base::PathService::Get(base::DIR_ANDROID_APP_DATA, &old_context_storage_path);
- if (!base::PathExists(context_storage_path)) {
- base::CreateDirectory(context_storage_path);
- }
- auto migrate_context_storage_data = [&old_context_storage_path,
- &context_storage_path](auto& suffix) {
- FilePath old_file = old_context_storage_path.Append(suffix);
- if (base::PathExists(old_file)) {
- FilePath new_file = context_storage_path.Append(suffix);
- if (base::PathExists(new_file)) {
- bool success =
- base::Move(new_file, new_file.AddExtension(".partial-migration"));
- DCHECK(success);
- }
- bool success = base::Move(old_file, new_file);
- DCHECK(success);
- }
- };
- // These were handled in the initial migration
- migrate_context_storage_data("Web Data");
- migrate_context_storage_data("Web Data-journal");
- migrate_context_storage_data("GPUCache");
- migrate_context_storage_data("blob_storage");
- migrate_context_storage_data("Session Storage");
- // These were missed in the initial migration
- migrate_context_storage_data("File System");
- migrate_context_storage_data("IndexedDB");
- migrate_context_storage_data("Local Storage");
- migrate_context_storage_data("QuotaManager");
- migrate_context_storage_data("QuotaManager-journal");
- migrate_context_storage_data("Service Worker");
- migrate_context_storage_data("VideoDecodeStats");
- migrate_context_storage_data("databases");
- migrate_context_storage_data("shared_proto_db");
- migrate_context_storage_data("webrtc_event_logs");
- }
- } // namespace
- AwBrowserContext::AwBrowserContext()
- : context_storage_path_(GetContextStoragePath()),
- simple_factory_key_(GetPath(), IsOffTheRecord()) {
- DCHECK(!g_browser_context);
- TRACE_EVENT0("startup", "AwBrowserContext::AwBrowserContext");
- profile_metrics::SetBrowserProfileType(
- this, profile_metrics::BrowserProfileType::kRegular);
- g_web_view_compat_crash_key.Set("0");
- if (IsDefaultBrowserContext()) {
- MigrateProfileData(GetCacheDir(), GetContextStoragePath());
- }
- g_browser_context = this;
- SimpleKeyMap::GetInstance()->Associate(this, &simple_factory_key_);
- CreateUserPrefService();
- visitedlink_writer_ =
- std::make_unique<visitedlink::VisitedLinkWriter>(this, this, false);
- visitedlink_writer_->Init();
- form_database_service_ =
- std::make_unique<AwFormDatabaseService>(context_storage_path_);
- EnsureResourceContextInitialized();
- // This constructor is entered during the creation of ContentBrowserClient,
- // before browser threads are created. Therefore any checks to enforce
- // threading (such as BrowserThread::CurrentlyOn()) will fail here.
- }
- AwBrowserContext::~AwBrowserContext() {
- DCHECK_EQ(this, g_browser_context);
- NotifyWillBeDestroyed();
- SimpleKeyMap::GetInstance()->Dissociate(this);
- ShutdownStoragePartitions();
- g_browser_context = NULL;
- }
- // static
- AwBrowserContext* AwBrowserContext::GetDefault() {
- // TODO(joth): rather than store in a global here, lookup this instance
- // from the Java-side peer.
- return g_browser_context;
- }
- // static
- AwBrowserContext* AwBrowserContext::FromWebContents(
- content::WebContents* web_contents) {
- // This is safe; this is the only implementation of the browser context.
- return static_cast<AwBrowserContext*>(web_contents->GetBrowserContext());
- }
- base::FilePath AwBrowserContext::GetCacheDir() {
- FilePath cache_path;
- if (!base::PathService::Get(base::DIR_CACHE, &cache_path)) {
- NOTREACHED() << "Failed to get app cache directory for Android WebView";
- }
- cache_path = cache_path.Append(FILE_PATH_LITERAL("Default"))
- .Append(FILE_PATH_LITERAL("HTTP Cache"));
- return cache_path;
- }
- base::FilePath AwBrowserContext::GetPrefStorePath() {
- FilePath pref_store_path;
- base::PathService::Get(base::DIR_ANDROID_APP_DATA, &pref_store_path);
- // TODO(amalova): Assign a proper file path for non-default profiles
- // when we support multiple profiles
- pref_store_path =
- pref_store_path.Append(FILE_PATH_LITERAL("Default/Preferences"));
- return pref_store_path;
- }
- base::FilePath AwBrowserContext::GetCookieStorePath() {
- return GetCookieManager()->GetCookieStorePath();
- }
- // static
- base::FilePath AwBrowserContext::GetContextStoragePath() {
- base::FilePath user_data_dir;
- if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) {
- NOTREACHED() << "Failed to get app data directory for Android WebView";
- }
- user_data_dir = user_data_dir.Append(FILE_PATH_LITERAL("Default"));
- return user_data_dir;
- }
- // static
- void AwBrowserContext::RegisterPrefs(PrefRegistrySimple* registry) {
- safe_browsing::RegisterProfilePrefs(registry);
- // Register the Autocomplete Data Retention Policy pref.
- // The default value '0' represents the latest Chrome major version on which
- // the retention policy ran. By setting it to a low default value, we're
- // making sure it runs now (as it only runs once per major version).
- registry->RegisterIntegerPref(
- autofill::prefs::kAutocompleteLastVersionRetentionPolicy, 0);
- // We only use the autocomplete feature of Autofill, which is controlled via
- // the manager_delegate. We don't use the rest of Autofill, which is why it is
- // hardcoded as disabled here.
- // TODO(crbug.com/873740): The following also disables autocomplete.
- // Investigate what the intended behavior is.
- registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled,
- false);
- registry->RegisterBooleanPref(autofill::prefs::kAutofillCreditCardEnabled,
- false);
- #if BUILDFLAG(ENABLE_MOJO_CDM)
- cdm::MediaDrmStorageImpl::RegisterProfilePrefs(registry);
- #endif
- }
- void AwBrowserContext::CreateUserPrefService() {
- TRACE_EVENT0("startup", "AwBrowserContext::CreateUserPrefService");
- auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
- RegisterPrefs(pref_registry.get());
- PrefServiceFactory pref_service_factory;
- std::set<std::string> persistent_prefs;
- // Persisted to avoid having to provision MediaDrm every time the
- // application tries to play protected content after restart.
- persistent_prefs.insert(cdm::prefs::kMediaDrmStorage);
- pref_service_factory.set_user_prefs(base::MakeRefCounted<SegregatedPrefStore>(
- base::MakeRefCounted<InMemoryPrefStore>(),
- base::MakeRefCounted<JsonPrefStore>(GetPrefStorePath()),
- std::move(persistent_prefs)));
- policy::URLBlocklistManager::RegisterProfilePrefs(pref_registry.get());
- AwBrowserPolicyConnector* browser_policy_connector =
- AwBrowserProcess::GetInstance()->browser_policy_connector();
- pref_service_factory.set_managed_prefs(
- base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>(
- browser_policy_connector,
- browser_policy_connector->GetPolicyService(),
- browser_policy_connector->GetHandlerList(),
- policy::POLICY_LEVEL_MANDATORY));
- user_pref_service_ = pref_service_factory.Create(pref_registry);
- if (IsDefaultBrowserContext()) {
- MigrateLocalStatePrefs();
- }
- user_prefs::UserPrefs::Set(this, user_pref_service_.get());
- }
- void AwBrowserContext::MigrateLocalStatePrefs() {
- PrefService* local_state = AwBrowserProcess::GetInstance()->local_state();
- if (!local_state->HasPrefPath(cdm::prefs::kMediaDrmStorage)) {
- return;
- }
- user_pref_service_->Set(cdm::prefs::kMediaDrmStorage,
- local_state->GetValue(cdm::prefs::kMediaDrmStorage));
- local_state->ClearPref(cdm::prefs::kMediaDrmStorage);
- }
- // static
- std::vector<std::string> AwBrowserContext::GetAuthSchemes() {
- // In Chrome this is configurable via the AuthSchemes policy. For WebView
- // there is no interest to have it available so far.
- std::vector<std::string> supported_schemes = {"basic", "digest", "ntlm",
- "negotiate"};
- return supported_schemes;
- }
- void AwBrowserContext::AddVisitedURLs(const std::vector<GURL>& urls) {
- DCHECK(visitedlink_writer_);
- visitedlink_writer_->AddURLs(urls);
- }
- AwQuotaManagerBridge* AwBrowserContext::GetQuotaManagerBridge() {
- if (!quota_manager_bridge_.get()) {
- quota_manager_bridge_ = AwQuotaManagerBridge::Create(this);
- }
- return quota_manager_bridge_.get();
- }
- void AwBrowserContext::SetWebLayerRunningInSameProcess(JNIEnv* env) {
- g_web_view_compat_crash_key.Set("1");
- }
- AwFormDatabaseService* AwBrowserContext::GetFormDatabaseService() {
- return form_database_service_.get();
- }
- autofill::AutocompleteHistoryManager*
- AwBrowserContext::GetAutocompleteHistoryManager() {
- if (!autocomplete_history_manager_) {
- autocomplete_history_manager_ =
- std::make_unique<autofill::AutocompleteHistoryManager>();
- autocomplete_history_manager_->Init(
- form_database_service_->get_autofill_webdata_service(),
- user_pref_service_.get(), IsOffTheRecord());
- }
- return autocomplete_history_manager_.get();
- }
- CookieManager* AwBrowserContext::GetCookieManager() {
- // TODO(amalova): create cookie manager for non-default profile
- return CookieManager::GetInstance();
- }
- base::FilePath AwBrowserContext::GetPath() {
- return context_storage_path_;
- }
- bool AwBrowserContext::IsOffTheRecord() {
- // Android WebView does not support off the record profile yet.
- return false;
- }
- content::ResourceContext* AwBrowserContext::GetResourceContext() {
- if (!resource_context_) {
- resource_context_ = std::make_unique<AwResourceContext>();
- }
- return resource_context_.get();
- }
- content::DownloadManagerDelegate*
- AwBrowserContext::GetDownloadManagerDelegate() {
- if (!GetUserData(kDownloadManagerDelegateKey)) {
- SetUserData(kDownloadManagerDelegateKey,
- std::make_unique<AwDownloadManagerDelegate>());
- }
- return static_cast<AwDownloadManagerDelegate*>(
- GetUserData(kDownloadManagerDelegateKey));
- }
- content::BrowserPluginGuestManager* AwBrowserContext::GetGuestManager() {
- return NULL;
- }
- storage::SpecialStoragePolicy* AwBrowserContext::GetSpecialStoragePolicy() {
- // Intentionally returning NULL as 'Extensions' and 'Apps' not supported.
- return NULL;
- }
- content::PlatformNotificationService*
- AwBrowserContext::GetPlatformNotificationService() {
- return nullptr;
- }
- content::PushMessagingService* AwBrowserContext::GetPushMessagingService() {
- // TODO(johnme): Support push messaging in WebView.
- return NULL;
- }
- content::StorageNotificationService*
- AwBrowserContext::GetStorageNotificationService() {
- return nullptr;
- }
- content::SSLHostStateDelegate* AwBrowserContext::GetSSLHostStateDelegate() {
- if (!ssl_host_state_delegate_.get()) {
- ssl_host_state_delegate_ = std::make_unique<AwSSLHostStateDelegate>();
- }
- return ssl_host_state_delegate_.get();
- }
- content::PermissionControllerDelegate*
- AwBrowserContext::GetPermissionControllerDelegate() {
- if (!permission_manager_.get())
- permission_manager_ = std::make_unique<AwPermissionManager>();
- return permission_manager_.get();
- }
- content::ClientHintsControllerDelegate*
- AwBrowserContext::GetClientHintsControllerDelegate() {
- return nullptr;
- }
- content::BackgroundFetchDelegate*
- AwBrowserContext::GetBackgroundFetchDelegate() {
- return nullptr;
- }
- content::BackgroundSyncController*
- AwBrowserContext::GetBackgroundSyncController() {
- return nullptr;
- }
- content::BrowsingDataRemoverDelegate*
- AwBrowserContext::GetBrowsingDataRemoverDelegate() {
- return nullptr;
- }
- content::ReduceAcceptLanguageControllerDelegate*
- AwBrowserContext::GetReduceAcceptLanguageControllerDelegate() {
- return nullptr;
- }
- download::InProgressDownloadManager*
- AwBrowserContext::RetriveInProgressDownloadManager() {
- return new download::InProgressDownloadManager(
- nullptr, base::FilePath(), nullptr,
- base::BindRepeating(&IgnoreOriginSecurityCheck),
- base::BindRepeating(&content::DownloadRequestUtils::IsURLSafe),
- /*wake_lock_provider_binder*/ base::NullCallback());
- }
- std::unique_ptr<content::ZoomLevelDelegate>
- AwBrowserContext::CreateZoomLevelDelegate(
- const base::FilePath& partition_path) {
- return nullptr;
- }
- void AwBrowserContext::RebuildTable(
- const scoped_refptr<URLEnumerator>& enumerator) {
- // Android WebView rebuilds from WebChromeClient.getVisitedHistory. The client
- // can change in the lifetime of this WebView and may not yet be set here.
- // Therefore this initialization path is not used.
- enumerator->OnComplete(true);
- }
- void AwBrowserContext::SetExtendedReportingAllowed(bool allowed) {
- user_pref_service_->SetBoolean(
- ::prefs::kSafeBrowsingExtendedReportingOptInAllowed, allowed);
- }
- // TODO(amalova): Make sure NetworkContextParams is configured correctly when
- // off-the-record
- void AwBrowserContext::ConfigureNetworkContextParams(
- bool in_memory,
- const base::FilePath& relative_partition_path,
- network::mojom::NetworkContextParams* context_params,
- cert_verifier::mojom::CertVerifierCreationParams*
- cert_verifier_creation_params) {
- context_params->user_agent = android_webview::GetUserAgent();
- // TODO(ntfschr): set this value to a proper value based on the user's
- // preferred locales (http://crbug.com/898555). For now, set this to
- // "en-US,en" instead of "en-us,en", since Android guarantees region codes
- // will be uppercase.
- context_params->accept_language =
- net::HttpUtil::GenerateAcceptLanguageHeader("en-US,en");
- // HTTP cache
- context_params->http_cache_enabled = true;
- context_params->http_cache_max_size = GetHttpCacheSize();
- context_params->http_cache_directory = GetCacheDir();
- // WebView should persist and restore cookies between app sessions (including
- // session cookies).
- context_params->file_paths = network::mojom::NetworkContextFilePaths::New();
- base::FilePath cookie_path = AwBrowserContext::GetCookieStorePath();
- context_params->file_paths->data_directory = cookie_path.DirName();
- context_params->file_paths->cookie_database_name = cookie_path.BaseName();
- context_params->restore_old_session_cookies = true;
- context_params->persist_session_cookies = true;
- context_params->cookie_manager_params =
- network::mojom::CookieManagerParams::New();
- context_params->cookie_manager_params->allow_file_scheme_cookies =
- GetCookieManager()->GetAllowFileSchemeCookies();
- context_params->cookie_manager_params->cookie_access_delegate_type =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kWebViewEnableModernCookieSameSite)
- ? network::mojom::CookieAccessDelegateType::ALWAYS_NONLEGACY
- : network::mojom::CookieAccessDelegateType::ALWAYS_LEGACY;
- context_params->initial_ssl_config = network::mojom::SSLConfig::New();
- // Allow SHA-1 to be used for locally-installed trust anchors, as WebView
- // should behave like the Android system would.
- context_params->initial_ssl_config->sha1_local_anchors_enabled = true;
- // Do not enforce the Legacy Symantec PKI policies outlined in
- // https://security.googleblog.com/2017/09/chromes-plan-to-distrust-symantec.html,
- // defer to the Android system.
- context_params->initial_ssl_config->symantec_enforcement_disabled = true;
- // Do not enforce Legacy TLS removal if support is still enabled.
- if (base::FeatureList::IsEnabled(
- android_webview::features::kWebViewLegacyTlsSupport)) {
- context_params->initial_ssl_config->version_min =
- network::mojom::SSLVersion::kTLS1;
- }
- // WebView does not currently support Certificate Transparency
- // (http://crbug.com/921750).
- context_params->enforce_chrome_ct_policy = false;
- context_params->enable_brotli = base::FeatureList::IsEnabled(
- android_webview::features::kWebViewBrotliSupport);
- context_params->check_clear_text_permitted =
- AwContentBrowserClient::get_check_cleartext_permitted();
- // Add proxy settings
- AwProxyConfigMonitor::GetInstance()->AddProxyToNetworkContextParams(
- context_params);
- }
- base::android::ScopedJavaLocalRef<jobject> JNI_AwBrowserContext_GetDefaultJava(
- JNIEnv* env) {
- return g_browser_context->GetJavaBrowserContext();
- }
- base::android::ScopedJavaLocalRef<jobject>
- AwBrowserContext::GetJavaBrowserContext() {
- if (!obj_) {
- JNIEnv* env = base::android::AttachCurrentThread();
- obj_ = Java_AwBrowserContext_create(env, reinterpret_cast<intptr_t>(this),
- IsDefaultBrowserContext());
- }
- return base::android::ScopedJavaLocalRef<jobject>(obj_);
- }
- jlong AwBrowserContext::GetQuotaManagerBridge(JNIEnv* env) {
- return reinterpret_cast<intptr_t>(GetQuotaManagerBridge());
- }
- } // namespace android_webview
|