| // Copyright 2015 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <jni.h> |
| |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/android/callback_android.h" |
| #include "base/android/jni_android.h" |
| #include "base/android/jni_array.h" |
| #include "base/android/jni_string.h" |
| #include "base/android/scoped_java_ref.h" |
| #include "base/check_op.h" |
| #include "base/containers/contains.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/json/json_reader.h" |
| #include "base/json/json_writer.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/notreached.h" |
| #include "base/ranges/algorithm.h" |
| #include "components/browser_ui/site_settings/android/site_settings_jni_headers/WebsitePreferenceBridge_jni.h" |
| #include "components/browser_ui/site_settings/android/storage_info_fetcher.h" |
| #include "components/browser_ui/site_settings/android/website_preference_bridge_util.h" |
| #include "components/browsing_data/content/cookie_helper.h" |
| #include "components/browsing_data/content/local_storage_helper.h" |
| #include "components/cdm/browser/media_drm_storage_impl.h" |
| #include "components/content_settings/browser/ui/cookie_controls_util.h" |
| #include "components/content_settings/core/browser/cookie_settings.h" |
| #include "components/content_settings/core/browser/host_content_settings_map.h" |
| #include "components/content_settings/core/common/content_settings.h" |
| #include "components/content_settings/core/common/content_settings_constraints.h" |
| #include "components/content_settings/core/common/content_settings_types.h" |
| #include "components/permissions/object_permission_context_base.h" |
| #include "components/permissions/permission_decision_auto_blocker.h" |
| #include "components/permissions/permission_manager.h" |
| #include "components/permissions/permission_uma_util.h" |
| #include "components/permissions/permission_util.h" |
| #include "components/permissions/permissions_client.h" |
| #include "components/user_prefs/user_prefs.h" |
| #include "content/public/browser/android/browser_context_handle.h" |
| #include "content/public/browser/browser_context.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/permission_controller.h" |
| #include "content/public/browser/permission_result.h" |
| #include "content/public/browser/storage_partition.h" |
| #include "net/cookies/cookie_util.h" |
| #include "net/extras/shared_dictionary/shared_dictionary_isolation_key.h" |
| #include "net/extras/shared_dictionary/shared_dictionary_usage_info.h" |
| #include "services/network/public/mojom/cookie_manager.mojom.h" |
| #include "services/network/public/mojom/network_context.mojom.h" |
| #include "storage/browser/quota/quota_manager.h" |
| #include "third_party/blink/public/common/storage_key/storage_key.h" |
| #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" |
| #include "url/android/gurl_android.h" |
| #include "url/origin.h" |
| #include "url/url_constants.h" |
| #include "url/url_util.h" |
| |
| using base::android::AttachCurrentThread; |
| using base::android::ConvertJavaStringToUTF8; |
| using base::android::ConvertUTF16ToJavaString; |
| using base::android::ConvertUTF8ToJavaString; |
| using base::android::JavaParamRef; |
| using base::android::JavaRef; |
| using base::android::ScopedJavaGlobalRef; |
| using base::android::ScopedJavaLocalRef; |
| using content::BrowserContext; |
| using content::BrowserThread; |
| using content_settings::CookieControlsUtil; |
| |
| namespace { |
| |
| const char kHttpPortSuffix[] = ":80"; |
| const char kHttpsPortSuffix[] = ":443"; |
| |
| BrowserContext* unwrap(const JavaParamRef<jobject>& jbrowser_context_handle) { |
| return content::BrowserContextFromJavaHandle(jbrowser_context_handle); |
| } |
| |
| HostContentSettingsMap* GetHostContentSettingsMap( |
| BrowserContext* browser_context) { |
| return permissions::PermissionsClient::Get()->GetSettingsMap(browser_context); |
| } |
| |
| HostContentSettingsMap* GetHostContentSettingsMap( |
| const JavaParamRef<jobject>& jbrowser_context_handle) { |
| return GetHostContentSettingsMap(unwrap(jbrowser_context_handle)); |
| } |
| |
| permissions::PermissionDecisionAutoBlocker* GetPermissionDecisionAutoBlocker( |
| BrowserContext* browser_context) { |
| return permissions::PermissionsClient::Get() |
| ->GetPermissionDecisionAutoBlocker(browser_context); |
| } |
| |
| ScopedJavaLocalRef<jstring> ConvertOriginToJavaString( |
| JNIEnv* env, |
| const std::string& origin) { |
| // The string |jorigin| is used to group permissions together in the Site |
| // Settings list. In order to group sites with the same origin, remove any |
| // standard port from the end of the URL if it's present (i.e. remove :443 |
| // for HTTPS sites and :80 for HTTP sites). |
| // TODO(mvanouwerkerk): Remove all this logic and take two passes through |
| // HostContentSettingsMap: once to get all the 'interesting' hosts, and once |
| // (on SingleWebsitePreferences) to find permission patterns which match |
| // each of these hosts. |
| if (base::StartsWith(origin, url::kHttpsScheme, |
| base::CompareCase::INSENSITIVE_ASCII) && |
| base::EndsWith(origin, kHttpsPortSuffix, |
| base::CompareCase::INSENSITIVE_ASCII)) { |
| return ConvertUTF8ToJavaString( |
| env, origin.substr(0, origin.size() - strlen(kHttpsPortSuffix))); |
| } else if (base::StartsWith(origin, url::kHttpScheme, |
| base::CompareCase::INSENSITIVE_ASCII) && |
| base::EndsWith(origin, kHttpPortSuffix, |
| base::CompareCase::INSENSITIVE_ASCII)) { |
| return ConvertUTF8ToJavaString( |
| env, origin.substr(0, origin.size() - strlen(kHttpPortSuffix))); |
| } else { |
| return ConvertUTF8ToJavaString(env, origin); |
| } |
| } |
| |
| typedef void (*InfoListInsertionFunction)( |
| JNIEnv*, |
| JniIntWrapper, |
| const base::android::JavaRef<jobject>&, |
| const base::android::JavaRef<jstring>&, |
| const base::android::JavaRef<jstring>&, |
| jboolean, |
| JniIntWrapper); |
| |
| void GetOrigins(JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType content_type, |
| InfoListInsertionFunction insertionFunc, |
| const JavaRef<jobject>& list, |
| jboolean managedOnly) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| HostContentSettingsMap* content_settings_map = |
| GetHostContentSettingsMap(browser_context); |
| |
| ContentSettingsForOneType all_settings = |
| content_settings_map->GetSettingsForOneType(content_type); |
| ContentSettingsForOneType embargo_settings = |
| content_settings_map->GetSettingsForOneType( |
| ContentSettingsType::PERMISSION_AUTOBLOCKER_DATA); |
| ContentSetting default_content_setting = |
| content_settings_map->GetDefaultContentSetting(content_type, nullptr); |
| |
| // Use a vector since the overall number of origins should be small. |
| std::vector<std::string> seen_origins; |
| |
| // Now add all origins that have a non-default setting to the list. |
| for (const auto& settings_it : all_settings) { |
| if (settings_it.GetContentSetting() == default_content_setting) |
| continue; |
| if (managedOnly && |
| HostContentSettingsMap::GetProviderTypeFromSource(settings_it.source) != |
| HostContentSettingsMap::ProviderType::POLICY_PROVIDER) { |
| continue; |
| } |
| const std::string origin = settings_it.primary_pattern.ToString(); |
| const std::string embedder = settings_it.secondary_pattern.ToString(); |
| |
| ScopedJavaLocalRef<jstring> jembedder; |
| if (embedder != origin) |
| jembedder = ConvertUTF8ToJavaString(env, embedder); |
| |
| seen_origins.push_back(origin); |
| insertionFunc(env, static_cast<int>(content_type), list, |
| ConvertOriginToJavaString(env, origin), jembedder, |
| /*is_embargoed=*/false, |
| static_cast<int>(settings_it.metadata.session_model())); |
| } |
| |
| // Add any origins which have a default content setting value (thus skipped |
| // above), but have been automatically blocked for this permission type. |
| // We use an empty embedder since embargo doesn't care about it. |
| permissions::PermissionDecisionAutoBlocker* auto_blocker = |
| permissions::PermissionsClient::Get()->GetPermissionDecisionAutoBlocker( |
| unwrap(jbrowser_context_handle)); |
| ScopedJavaLocalRef<jstring> jembedder; |
| |
| for (const auto& settings_it : embargo_settings) { |
| const std::string origin = settings_it.primary_pattern.ToString(); |
| if (base::Contains(seen_origins, origin)) { |
| // This origin has already been added to the list, so don't add it again. |
| continue; |
| } |
| |
| if (auto_blocker->IsEmbargoed(GURL(origin), content_type)) { |
| seen_origins.push_back(origin); |
| insertionFunc(env, static_cast<int>(content_type), list, |
| ConvertOriginToJavaString(env, origin), jembedder, |
| /*is_embargoed=*/true, /*is_one_time=*/false); |
| } |
| } |
| } |
| |
| ContentSetting GetPermissionSettingForOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType content_type, |
| jstring origin, |
| jstring embedder) { |
| GURL requesting_origin(ConvertJavaStringToUTF8(env, origin)); |
| std::string embedder_str = ConvertJavaStringToUTF8(env, embedder); |
| GURL embedding_origin; |
| // TODO(raymes): This check to see if '*' is the embedder is a hack that fixes |
| // crbug.com/738377. In general querying the settings for patterns is broken |
| // and needs to be fixed. See crbug.com/738757. |
| if (embedder_str == "*") |
| embedding_origin = requesting_origin; |
| else |
| embedding_origin = GURL(embedder_str); |
| |
| // If `content_type` is permission, then we need to apply a set of |
| // verifications before reading its value in `HostContentSettingsMap`. |
| if (permissions::PermissionUtil::IsPermission(content_type)) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| content::PermissionController* permission_controller = |
| browser_context->GetPermissionController(); |
| content::PermissionResult result = |
| permission_controller->GetPermissionResultForOriginWithoutContext( |
| permissions::PermissionUtil::ContentSettingTypeToPermissionType( |
| content_type), |
| url::Origin::Create(requesting_origin), |
| url::Origin::Create(embedding_origin)); |
| return permissions::PermissionUtil::PermissionStatusToContentSetting( |
| result.status); |
| } else { |
| // If `content_type` is not permission, then we can directly read its value |
| // from `HostContentSettingsMap`. |
| HostContentSettingsMap* host_content_settings_map = |
| GetHostContentSettingsMap(jbrowser_context_handle); |
| return host_content_settings_map->GetContentSetting( |
| requesting_origin, embedding_origin, content_type); |
| } |
| } |
| |
| void SetPermissionSettingForOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType content_type, |
| jstring origin, |
| jstring embedder, |
| ContentSetting setting) { |
| GURL origin_url(ConvertJavaStringToUTF8(env, origin)); |
| GURL embedder_url = |
| embedder ? GURL(ConvertJavaStringToUTF8(env, embedder)) : GURL(); |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| |
| // The permission may have been blocked due to being under embargo, so if it |
| // was changed away from BLOCK, clear embargo status if it exists. |
| if (setting != CONTENT_SETTING_BLOCK) { |
| GetPermissionDecisionAutoBlocker(browser_context) |
| ->RemoveEmbargoAndResetCounts(origin_url, content_type); |
| } |
| |
| permissions::PermissionUmaUtil::ScopedRevocationReporter |
| scoped_revocation_reporter( |
| browser_context, origin_url, embedder_url, content_type, |
| permissions::PermissionSourceUI::SITE_SETTINGS); |
| GetHostContentSettingsMap(browser_context) |
| ->SetContentSettingDefaultScope(origin_url, embedder_url, content_type, |
| setting); |
| } |
| |
| permissions::ObjectPermissionContextBase* GetChooserContext( |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType type) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| return permissions::PermissionsClient::Get()->GetChooserContext( |
| browser_context, type); |
| } |
| |
| bool OriginMatcher(const url::Origin& origin, const GURL& other) { |
| return origin == url::Origin::Create(other); |
| } |
| |
| bool GetBooleanForContentSetting( |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType type) { |
| HostContentSettingsMap* content_settings = |
| GetHostContentSettingsMap(jbrowser_context_handle); |
| switch (content_settings->GetDefaultContentSetting(type, nullptr)) { |
| case CONTENT_SETTING_BLOCK: |
| return false; |
| case CONTENT_SETTING_ALLOW: |
| case CONTENT_SETTING_ASK: |
| default: |
| return true; |
| } |
| } |
| |
| bool IsContentSettingManaged( |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType content_settings_type) { |
| std::string source; |
| HostContentSettingsMap* content_settings = |
| GetHostContentSettingsMap(jbrowser_context_handle); |
| content_settings->GetDefaultContentSetting(content_settings_type, &source); |
| HostContentSettingsMap::ProviderType provider = |
| content_settings->GetProviderTypeFromSource(source); |
| return provider == HostContentSettingsMap::POLICY_PROVIDER; |
| } |
| |
| bool IsContentSettingManagedByCustodian( |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType content_settings_type) { |
| std::string source; |
| HostContentSettingsMap* content_settings = |
| GetHostContentSettingsMap(jbrowser_context_handle); |
| content_settings->GetDefaultContentSetting(content_settings_type, &source); |
| HostContentSettingsMap::ProviderType provider = |
| content_settings->GetProviderTypeFromSource(source); |
| return provider == HostContentSettingsMap::SUPERVISED_PROVIDER; |
| } |
| |
| bool IsContentSettingUserModifiable( |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| ContentSettingsType content_settings_type) { |
| std::string source; |
| HostContentSettingsMap* content_settings = |
| GetHostContentSettingsMap(jbrowser_context_handle); |
| content_settings->GetDefaultContentSetting(content_settings_type, &source); |
| HostContentSettingsMap::ProviderType provider = |
| content_settings->GetProviderTypeFromSource(source); |
| return provider >= HostContentSettingsMap::PREF_PROVIDER; |
| } |
| |
| } // anonymous namespace |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsNotificationEmbargoedForOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& origin) { |
| GURL origin_url(ConvertJavaStringToUTF8(env, origin)); |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| permissions::PermissionDecisionAutoBlocker* auto_blocker = |
| GetPermissionDecisionAutoBlocker(browser_context); |
| |
| return auto_blocker->IsEmbargoed(origin_url, |
| ContentSettingsType::NOTIFICATIONS); |
| } |
| |
| static void SetNotificationSettingForOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& origin, |
| jint value) { |
| // Note: For Android O+, SetNotificationSettingForOrigin is only called when: |
| // 1) the "Clear & Reset" button in Site Settings is pressed, |
| // 2) the notification permission is blocked by embargo, so no notification |
| // channel exists yet, and in this state the user changes the setting to |
| // allow or "real" block in SingleWebsitePreferences. |
| // Otherwise, we rely on ReportNotificationRevokedForOrigin to explicitly |
| // record metrics when we detect changes initiated in Android. |
| // |
| // Note: Web Notification permission behaves differently from all other |
| // permission types. See https://crbug.com/416894. |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| GURL url = GURL(ConvertJavaStringToUTF8(env, origin)); |
| ContentSetting setting = static_cast<ContentSetting>(value); |
| |
| GetPermissionDecisionAutoBlocker(browser_context) |
| ->RemoveEmbargoAndResetCounts(url, ContentSettingsType::NOTIFICATIONS); |
| |
| permissions::PermissionUmaUtil::ScopedRevocationReporter |
| scoped_revocation_reporter( |
| browser_context, url, GURL(), ContentSettingsType::NOTIFICATIONS, |
| permissions::PermissionSourceUI::SITE_SETTINGS); |
| |
| GetHostContentSettingsMap(browser_context) |
| ->SetContentSettingDefaultScope( |
| url, GURL(), ContentSettingsType::NOTIFICATIONS, setting); |
| } |
| |
| // In Android O+, Android is responsible for revoking notification settings-- |
| // We detect this change and explicitly report it back for UMA reporting. |
| static void JNI_WebsitePreferenceBridge_ReportNotificationRevokedForOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& origin, |
| jint new_setting_value) { |
| GURL url = GURL(ConvertJavaStringToUTF8(env, origin)); |
| |
| ContentSetting setting = static_cast<ContentSetting>(new_setting_value); |
| DCHECK_NE(setting, CONTENT_SETTING_ALLOW); |
| |
| permissions::PermissionUmaUtil::PermissionRevoked( |
| ContentSettingsType::NOTIFICATIONS, |
| permissions::PermissionSourceUI::ANDROID_SETTINGS, |
| url.DeprecatedGetOriginAsURL(), unwrap(jbrowser_context_handle)); |
| } |
| |
| static jint JNI_WebsitePreferenceBridge_GetPermissionSettingForOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| jint content_settings_type, |
| const JavaParamRef<jstring>& origin, |
| const JavaParamRef<jstring>& embedder) { |
| ContentSettingsType type = |
| static_cast<ContentSettingsType>(content_settings_type); |
| return GetPermissionSettingForOrigin(env, jbrowser_context_handle, type, |
| origin, embedder); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_SetPermissionSettingForOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| jint content_settings_type, |
| const JavaParamRef<jstring>& origin, |
| const JavaParamRef<jstring>& embedder, |
| jint value) { |
| ContentSettingsType type = |
| static_cast<ContentSettingsType>(content_settings_type); |
| |
| switch (type) { |
| case ContentSettingsType::NOTIFICATIONS: |
| return SetNotificationSettingForOrigin(env, jbrowser_context_handle, |
| origin, value); |
| case ContentSettingsType::MEDIASTREAM_MIC: |
| case ContentSettingsType::MEDIASTREAM_CAMERA: |
| return SetPermissionSettingForOrigin(env, jbrowser_context_handle, type, |
| origin, nullptr, |
| static_cast<ContentSetting>(value)); |
| default: |
| SetPermissionSettingForOrigin(env, jbrowser_context_handle, type, origin, |
| embedder, |
| static_cast<ContentSetting>(value)); |
| } |
| } |
| |
| static void JNI_WebsitePreferenceBridge_SetEphemeralGrantForTesting( // IN-TEST |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| jint content_settings_type, |
| const JavaParamRef<jobject>& jprimary_url, |
| const JavaParamRef<jobject>& jsecondary_url) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| content_settings::ContentSettingConstraints constraints; |
| constraints.set_session_model(content_settings::SessionModel::OneTime); |
| GetHostContentSettingsMap(browser_context) |
| ->SetContentSettingDefaultScope( |
| *url::GURLAndroid::ToNativeGURL(env, jprimary_url), |
| *url::GURLAndroid::ToNativeGURL(env, jsecondary_url), |
| static_cast<ContentSettingsType>(content_settings_type), |
| CONTENT_SETTING_ALLOW, constraints); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_GetOriginsForPermission( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| jint content_settings_type, |
| const JavaParamRef<jobject>& list, |
| jboolean managedOnly) { |
| GetOrigins(env, jbrowser_context_handle, |
| static_cast<ContentSettingsType>(content_settings_type), |
| &Java_WebsitePreferenceBridge_insertPermissionInfoIntoList, list, |
| managedOnly); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsContentSettingsPatternValid( |
| JNIEnv* env, |
| const JavaParamRef<jstring>& pattern) { |
| return ContentSettingsPattern::FromString( |
| ConvertJavaStringToUTF8(env, pattern)) |
| .IsValid(); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_UrlMatchesContentSettingsPattern( |
| JNIEnv* env, |
| const JavaParamRef<jstring>& jurl, |
| const JavaParamRef<jstring>& jpattern) { |
| ContentSettingsPattern pattern = ContentSettingsPattern::FromString( |
| ConvertJavaStringToUTF8(env, jpattern)); |
| return pattern.Matches(GURL(ConvertJavaStringToUTF8(env, jurl))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_GetChosenObjects( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| jint content_settings_type, |
| const JavaParamRef<jobject>& list) { |
| ContentSettingsType type = |
| static_cast<ContentSettingsType>(content_settings_type); |
| permissions::ObjectPermissionContextBase* context = |
| GetChooserContext(jbrowser_context_handle, type); |
| // The ObjectPermissionContextBase can be null if the embedder doesn't support |
| // the given ContentSettingsType. |
| if (!context) |
| return; |
| for (const auto& object : context->GetAllGrantedObjects()) { |
| // Remove the trailing slash so that origins are matched correctly in |
| // SingleWebsitePreferences.mergePermissionInfoForTopLevelOrigin. |
| std::string origin = object->origin.spec(); |
| DCHECK_EQ('/', origin.back()); |
| origin.pop_back(); |
| ScopedJavaLocalRef<jstring> jorigin = ConvertUTF8ToJavaString(env, origin); |
| |
| ScopedJavaLocalRef<jstring> jname = ConvertUTF16ToJavaString( |
| env, context->GetObjectDisplayName(object->value)); |
| |
| std::string serialized; |
| bool written = base::JSONWriter::Write(object->value, &serialized); |
| DCHECK(written); |
| ScopedJavaLocalRef<jstring> jserialized = |
| ConvertUTF8ToJavaString(env, serialized); |
| |
| jboolean jis_managed = |
| object->source == content_settings::SETTING_SOURCE_POLICY; |
| |
| Java_WebsitePreferenceBridge_insertChosenObjectInfoIntoList( |
| env, list, content_settings_type, jorigin, jname, jserialized, |
| jis_managed); |
| } |
| } |
| |
| static void JNI_WebsitePreferenceBridge_RevokeObjectPermission( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| jint content_settings_type, |
| const JavaParamRef<jstring>& jorigin, |
| const JavaParamRef<jstring>& jobject) { |
| GURL origin(ConvertJavaStringToUTF8(env, jorigin)); |
| DCHECK(origin.is_valid()); |
| std::optional<base::Value> object = |
| base::JSONReader::Read(ConvertJavaStringToUTF8(env, jobject)); |
| DCHECK(object && object->is_dict()); |
| permissions::ObjectPermissionContextBase* context = GetChooserContext( |
| jbrowser_context_handle, |
| static_cast<ContentSettingsType>(content_settings_type)); |
| context->RevokeObjectPermission(url::Origin::Create(origin), |
| object->GetDict()); |
| } |
| |
| namespace { |
| |
| void OnCookiesReceived(network::mojom::CookieManager* cookie_manager, |
| const GURL& domain, |
| const std::vector<net::CanonicalCookie>& cookies) { |
| for (const auto& cookie : cookies) { |
| if (cookie.IsDomainMatch(domain.host())) { |
| cookie_manager->DeleteCanonicalCookie(cookie, base::DoNothing()); |
| } |
| } |
| } |
| |
| void OnCookiesInfoReady(const ScopedJavaGlobalRef<jobject>& java_callback, |
| const net::CookieList& entries) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jobject> map = |
| Java_WebsitePreferenceBridge_createCookiesInfoMap(env); |
| |
| for (const net::CanonicalCookie& cookie : entries) { |
| std::string origin = net::cookie_util::CookieOriginToURL( |
| cookie.Domain(), cookie.SecureAttribute()) |
| .spec(); |
| ScopedJavaLocalRef<jstring> java_origin = |
| ConvertUTF8ToJavaString(env, origin); |
| Java_WebsitePreferenceBridge_insertCookieIntoMap(env, map, java_origin); |
| } |
| |
| base::android::RunObjectCallbackAndroid(java_callback, map); |
| } |
| |
| void OnStorageInfoReady(const ScopedJavaGlobalRef<jobject>& java_callback, |
| const storage::UsageInfoEntries& entries) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jobject> list = |
| Java_WebsitePreferenceBridge_createStorageInfoList(env); |
| |
| storage::UsageInfoEntries::const_iterator i; |
| for (i = entries.begin(); i != entries.end(); ++i) { |
| if (i->usage <= 0) |
| continue; |
| ScopedJavaLocalRef<jstring> host = ConvertUTF8ToJavaString(env, i->host); |
| |
| Java_WebsitePreferenceBridge_insertStorageInfoIntoList( |
| env, list, host, static_cast<jint>(i->type), i->usage); |
| } |
| |
| base::android::RunObjectCallbackAndroid(java_callback, list); |
| } |
| |
| void OnLocalStorageCleared(const ScopedJavaGlobalRef<jobject>& java_callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| |
| Java_StorageInfoClearedCallback_onStorageInfoCleared( |
| base::android::AttachCurrentThread(), java_callback); |
| } |
| |
| void OnStorageInfoCleared(const ScopedJavaGlobalRef<jobject>& java_callback, |
| blink::mojom::QuotaStatusCode code) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| |
| Java_StorageInfoClearedCallback_onStorageInfoCleared( |
| base::android::AttachCurrentThread(), java_callback); |
| } |
| |
| void OnLocalStorageModelInfoLoaded( |
| BrowserContext* browser_context, |
| bool fetch_important, |
| const ScopedJavaGlobalRef<jobject>& java_callback, |
| const std::list<content::StorageUsageInfo>& local_storage_info) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jobject> map = |
| Java_WebsitePreferenceBridge_createLocalStorageInfoMap(env); |
| |
| std::vector<std::pair<url::Origin, bool>> important_notations( |
| local_storage_info.size()); |
| base::ranges::transform(local_storage_info, important_notations.begin(), |
| [](const content::StorageUsageInfo& info) { |
| return std::make_pair(info.storage_key.origin(), |
| false); |
| }); |
| if (fetch_important) { |
| permissions::PermissionsClient::Get()->AreSitesImportant( |
| browser_context, &important_notations); |
| } |
| |
| int i = 0; |
| for (const content::StorageUsageInfo& info : local_storage_info) { |
| ScopedJavaLocalRef<jstring> java_origin = |
| ConvertUTF8ToJavaString(env, info.storage_key.origin().Serialize()); |
| Java_WebsitePreferenceBridge_insertLocalStorageInfoIntoMap( |
| env, map, java_origin, info.total_size_bytes, |
| important_notations[i++].second); |
| } |
| |
| base::android::RunObjectCallbackAndroid(java_callback, map); |
| } |
| |
| void OnSharedDictionaryInfoLoaded( |
| BrowserContext* browser_context, |
| const ScopedJavaGlobalRef<jobject>& java_callback, |
| const std::vector<net::SharedDictionaryUsageInfo>& shared_dictionary_info) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| |
| ScopedJavaLocalRef<jobject> list = |
| Java_WebsitePreferenceBridge_createSharedDictionaryInfoList(env); |
| for (const auto& info : shared_dictionary_info) { |
| ScopedJavaLocalRef<jstring> java_origin = ConvertUTF8ToJavaString( |
| env, info.isolation_key.frame_origin().Serialize()); |
| ScopedJavaLocalRef<jstring> java_top_frame_site = ConvertUTF8ToJavaString( |
| env, info.isolation_key.top_frame_site().Serialize()); |
| Java_WebsitePreferenceBridge_insertSharedDictionaryInfoIntoList( |
| env, list, java_origin, java_top_frame_site, info.total_size_bytes); |
| } |
| base::android::RunObjectCallbackAndroid(java_callback, list); |
| } |
| |
| } // anonymous namespace |
| |
| // TODO(jknotten): These methods should not be static. Instead we should |
| // expose a class to Java so that the fetch requests can be cancelled, |
| // and manage the lifetimes of the callback (and indirectly the helper |
| // by having a reference to it). |
| |
| // The helper methods (StartFetching, DeleteLocalStorageFile, DeleteDatabase) |
| // are asynchronous. A "use after free" error is not possible because the |
| // helpers keep a reference to themselves for the duration of their tasks, |
| // which includes callback invocation. |
| |
| static void JNI_WebsitePreferenceBridge_FetchCookiesInfo( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jobject>& java_callback) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| auto cookie_helper = base::MakeRefCounted<browsing_data::CookieHelper>( |
| browser_context->GetDefaultStoragePartition(), base::NullCallback()); |
| cookie_helper->StartFetching(base::BindOnce( |
| &OnCookiesInfoReady, ScopedJavaGlobalRef<jobject>(java_callback))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_FetchLocalStorageInfo( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jobject>& java_callback, |
| jboolean fetch_important) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| auto local_storage_helper = |
| base::MakeRefCounted<browsing_data::LocalStorageHelper>( |
| browser_context->GetDefaultStoragePartition()); |
| local_storage_helper->StartFetching(base::BindOnce( |
| &OnLocalStorageModelInfoLoaded, browser_context, fetch_important, |
| ScopedJavaGlobalRef<jobject>(java_callback))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_FetchStorageInfo( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jobject>& java_callback) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| |
| auto storage_info_fetcher = |
| base::MakeRefCounted<browser_ui::StorageInfoFetcher>(browser_context); |
| storage_info_fetcher->FetchStorageInfo(base::BindOnce( |
| &OnStorageInfoReady, ScopedJavaGlobalRef<jobject>(java_callback))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_FetchSharedDictionaryInfo( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jobject>& java_callback) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| browser_context->GetDefaultStoragePartition() |
| ->GetNetworkContext() |
| ->GetSharedDictionaryUsageInfo( |
| base::BindOnce(&OnSharedDictionaryInfoLoaded, browser_context, |
| ScopedJavaGlobalRef<jobject>(java_callback))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_ClearLocalStorageData( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin, |
| const JavaParamRef<jobject>& java_callback) { |
| ClearLocalStorageHelper::ClearLocalStorage( |
| unwrap(jbrowser_context_handle), |
| url::Origin::Create(GURL(ConvertJavaStringToUTF8(env, jorigin))), |
| base::BindOnce(&OnLocalStorageCleared, |
| ScopedJavaGlobalRef<jobject>(java_callback))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_ClearSharedDictionary( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin, |
| const JavaParamRef<jstring>& jtop_level_site, |
| const JavaParamRef<jobject>& java_callback) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| browser_context->GetDefaultStoragePartition() |
| ->GetNetworkContext() |
| ->ClearSharedDictionaryCacheForIsolationKey( |
| net::SharedDictionaryIsolationKey( |
| url::Origin::Create(GURL(ConvertJavaStringToUTF8(env, jorigin))), |
| net::SchemefulSite( |
| GURL(ConvertJavaStringToUTF8(env, jtop_level_site)))), |
| base::BindOnce( |
| [](const ScopedJavaGlobalRef<jobject>& java_callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| Java_StorageInfoClearedCallback_onStorageInfoCleared( |
| base::android::AttachCurrentThread(), java_callback); |
| }, |
| ScopedJavaGlobalRef<jobject>(java_callback))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_ClearStorageData( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jhost, |
| jint type, |
| const JavaParamRef<jobject>& java_callback) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| std::string host = ConvertJavaStringToUTF8(env, jhost); |
| |
| auto storage_info_fetcher = |
| base::MakeRefCounted<browser_ui::StorageInfoFetcher>(browser_context); |
| storage_info_fetcher->ClearStorage( |
| host, static_cast<blink::mojom::StorageType>(type), |
| base::BindOnce(&OnStorageInfoCleared, |
| ScopedJavaGlobalRef<jobject>(java_callback))); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_ClearCookieData( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| GURL url(ConvertJavaStringToUTF8(env, jorigin)); |
| |
| auto* storage_partition = browser_context->GetDefaultStoragePartition(); |
| auto* cookie_manager = storage_partition->GetCookieManagerForBrowserProcess(); |
| cookie_manager->GetAllCookies( |
| base::BindOnce(&OnCookiesReceived, cookie_manager, url)); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_ClearBannerData( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin) { |
| GetHostContentSettingsMap(jbrowser_context_handle) |
| ->SetWebsiteSettingDefaultScope( |
| GURL(ConvertJavaStringToUTF8(env, jorigin)), GURL(), |
| ContentSettingsType::APP_BANNER, base::Value()); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_ClearMediaLicenses( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| url::Origin origin = |
| url::Origin::Create(GURL(ConvertJavaStringToUTF8(env, jorigin))); |
| cdm::MediaDrmStorageImpl::ClearMatchingLicenses( |
| user_prefs::UserPrefs::Get(browser_context), base::Time(), |
| base::Time::Max(), base::BindRepeating(&OriginMatcher, origin), |
| base::DoNothing()); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsDSEOrigin( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin) { |
| return permissions::PermissionsClient::Get()->IsDseOrigin( |
| unwrap(jbrowser_context_handle), |
| url::Origin::Create(GURL(ConvertJavaStringToUTF8(env, jorigin)))); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_GetAdBlockingActivated( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin) { |
| GURL url(ConvertJavaStringToUTF8(env, jorigin)); |
| return permissions::PermissionsClient::Get()->IsSubresourceFilterActivated( |
| unwrap(jbrowser_context_handle), url); |
| } |
| |
| // On Android O+ notification channels are not stored in the Chrome profile |
| // and so are persisted across tests. This function resets them. |
| static void JNI_WebsitePreferenceBridge_ResetNotificationsSettingsForTest( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle) { |
| GetHostContentSettingsMap(jbrowser_context_handle) |
| ->ClearSettingsForOneType(ContentSettingsType::NOTIFICATIONS); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsContentSettingManaged( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type) { |
| return IsContentSettingManaged( |
| jbrowser_context_handle, |
| static_cast<ContentSettingsType>(content_settings_type)); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsCookieDeletionDisabled( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| const JavaParamRef<jstring>& jorigin) { |
| std::string origin = ConvertJavaStringToUTF8(env, jorigin); |
| return permissions::PermissionsClient::Get()->IsCookieDeletionDisabled( |
| unwrap(jbrowser_context_handle), GURL(origin)); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsContentSettingEnabled( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type) { |
| ContentSettingsType type = |
| static_cast<ContentSettingsType>(content_settings_type); |
| |
| return GetBooleanForContentSetting(jbrowser_context_handle, type); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_SetContentSettingEnabled( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type, |
| jboolean allow) { |
| ContentSettingsType type = |
| static_cast<ContentSettingsType>(content_settings_type); |
| |
| if (type == ContentSettingsType::SOUND) { |
| if (allow) { |
| base::RecordAction(base::UserMetricsAction( |
| "SoundContentSetting.UnmuteBy.DefaultSwitch")); |
| } else { |
| base::RecordAction( |
| base::UserMetricsAction("SoundContentSetting.MuteBy.DefaultSwitch")); |
| } |
| } |
| |
| ContentSetting value = CONTENT_SETTING_BLOCK; |
| if (allow) { |
| switch (type) { |
| case ContentSettingsType::AR: |
| case ContentSettingsType::AUTOMATIC_DOWNLOADS: |
| case ContentSettingsType::BLUETOOTH_GUARD: |
| case ContentSettingsType::BLUETOOTH_SCANNING: |
| case ContentSettingsType::CLIPBOARD_READ_WRITE: |
| case ContentSettingsType::GEOLOCATION: |
| case ContentSettingsType::IDLE_DETECTION: |
| case ContentSettingsType::MEDIASTREAM_CAMERA: |
| case ContentSettingsType::MEDIASTREAM_MIC: |
| case ContentSettingsType::NFC: |
| case ContentSettingsType::NOTIFICATIONS: |
| case ContentSettingsType::STORAGE_ACCESS: |
| case ContentSettingsType::USB_GUARD: |
| case ContentSettingsType::VR: |
| value = CONTENT_SETTING_ASK; |
| break; |
| case ContentSettingsType::ADS: |
| case ContentSettingsType::ANTI_ABUSE: |
| case ContentSettingsType::AUTO_DARK_WEB_CONTENT: |
| case ContentSettingsType::BACKGROUND_SYNC: |
| case ContentSettingsType::COOKIES: |
| case ContentSettingsType::FEDERATED_IDENTITY_API: |
| case ContentSettingsType::JAVASCRIPT: |
| case ContentSettingsType::POPUPS: |
| case ContentSettingsType::REQUEST_DESKTOP_SITE: |
| case ContentSettingsType::SENSORS: |
| case ContentSettingsType::SOUND: |
| value = CONTENT_SETTING_ALLOW; |
| break; |
| default: |
| NOTREACHED() << static_cast<int>(type); // Not supported on Android. |
| } |
| } |
| |
| GetHostContentSettingsMap(jbrowser_context_handle) |
| ->SetDefaultContentSetting(type, value); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_SetContentSettingDefaultScope( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type, |
| const JavaParamRef<jobject>& jprimary_url, |
| const JavaParamRef<jobject>& jsecondary_url, |
| int setting) { |
| GURL primary_url = *url::GURLAndroid::ToNativeGURL(env, jprimary_url); |
| if (setting != CONTENT_SETTING_BLOCK) { |
| GetPermissionDecisionAutoBlocker(unwrap(jbrowser_context_handle)) |
| ->RemoveEmbargoAndResetCounts( |
| primary_url, |
| static_cast<ContentSettingsType>(content_settings_type)); |
| } |
| GetHostContentSettingsMap(jbrowser_context_handle) |
| ->SetContentSettingDefaultScope( |
| primary_url, *url::GURLAndroid::ToNativeGURL(env, jsecondary_url), |
| static_cast<ContentSettingsType>(content_settings_type), |
| static_cast<ContentSetting>(setting)); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_SetContentSettingCustomScope( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type, |
| const JavaParamRef<jstring>& primary_pattern, |
| const JavaParamRef<jstring>& secondary_pattern, |
| int setting) { |
| std::string primary_pattern_string = |
| ConvertJavaStringToUTF8(env, primary_pattern); |
| GURL primary_url(primary_pattern_string); |
| if (setting != CONTENT_SETTING_BLOCK && primary_url.is_valid()) { |
| GetPermissionDecisionAutoBlocker(unwrap(jbrowser_context_handle)) |
| ->RemoveEmbargoAndResetCounts( |
| primary_url, |
| static_cast<ContentSettingsType>(content_settings_type)); |
| } |
| |
| std::string secondary_pattern_string = |
| ConvertJavaStringToUTF8(env, secondary_pattern); |
| GetHostContentSettingsMap(jbrowser_context_handle) |
| ->SetContentSettingCustomScope( |
| ContentSettingsPattern::FromString(primary_pattern_string), |
| secondary_pattern_string.empty() |
| ? ContentSettingsPattern::Wildcard() |
| : ContentSettingsPattern::FromString(secondary_pattern_string), |
| static_cast<ContentSettingsType>(content_settings_type), |
| static_cast<ContentSetting>(setting)); |
| } |
| |
| static int JNI_WebsitePreferenceBridge_GetContentSetting( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type, |
| const JavaParamRef<jobject>& jprimary_url, |
| const JavaParamRef<jobject>& jsecondary_url) { |
| return GetHostContentSettingsMap(jbrowser_context_handle) |
| ->GetContentSetting( |
| *url::GURLAndroid::ToNativeGURL(env, jprimary_url), |
| *url::GURLAndroid::ToNativeGURL(env, jsecondary_url), |
| static_cast<ContentSettingsType>(content_settings_type)); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsContentSettingGlobal( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type, |
| const JavaParamRef<jobject>& jprimary_url, |
| const JavaParamRef<jobject>& jsecondary_url) { |
| content_settings::SettingInfo setting_info; |
| GetHostContentSettingsMap(jbrowser_context_handle) |
| ->GetContentSetting( |
| *url::GURLAndroid::ToNativeGURL(env, jprimary_url), |
| *url::GURLAndroid::ToNativeGURL(env, jsecondary_url), |
| static_cast<ContentSettingsType>(content_settings_type), |
| &setting_info); |
| return setting_info.primary_pattern == ContentSettingsPattern::Wildcard() && |
| setting_info.secondary_pattern == ContentSettingsPattern::Wildcard(); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_GetContentSettingsExceptions( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type, |
| const JavaParamRef<jobject>& list) { |
| BrowserContext* browser_context = unwrap(jbrowser_context_handle); |
| std::vector<std::string> seen_origins; |
| for (const ContentSettingPatternSource& entry : |
| GetHostContentSettingsMap(browser_context) |
| ->GetSettingsForOneType( |
| static_cast<ContentSettingsType>(content_settings_type))) { |
| std::string origin = entry.primary_pattern.ToString(); |
| seen_origins.push_back(origin); |
| auto hasExpiration = !entry.metadata.expiration().is_null(); |
| auto expirationInDays = hasExpiration |
| ? CookieControlsUtil::GetDaysToExpiration( |
| entry.metadata.expiration()) |
| : -1; |
| Java_WebsitePreferenceBridge_addContentSettingExceptionToList( |
| env, list, content_settings_type, ConvertUTF8ToJavaString(env, origin), |
| ConvertUTF8ToJavaString(env, entry.secondary_pattern.ToString()), |
| entry.GetContentSetting(), ConvertUTF8ToJavaString(env, entry.source), |
| hasExpiration, expirationInDays, |
| /*is_embargoed=*/false); |
| } |
| |
| // Add any origins which have been automatically blocked for this content |
| // setting. We use an empty embedder since embargo doesn't care about it. |
| std::set<GURL> embargoed_origins = |
| GetPermissionDecisionAutoBlocker(browser_context) |
| ->GetEmbargoedOrigins( |
| static_cast<ContentSettingsType>(content_settings_type)); |
| ScopedJavaLocalRef<jstring> jembedder; |
| for (const GURL& embargoed_origin : embargoed_origins) { |
| if (base::Contains(seen_origins, embargoed_origin.spec())) |
| continue; |
| std::string embargoed_origin_pattern = |
| ContentSettingsPattern::FromURLNoWildcard(embargoed_origin).ToString(); |
| Java_WebsitePreferenceBridge_addContentSettingExceptionToList( |
| env, list, content_settings_type, |
| ConvertUTF8ToJavaString(env, embargoed_origin_pattern), jembedder, |
| CONTENT_SETTING_BLOCK, /*source=*/ScopedJavaLocalRef<jstring>(), |
| /*isTemporary=*/false, |
| /*expiration=*/0, /*is_embargoed=*/true); |
| } |
| } |
| |
| static jint JNI_WebsitePreferenceBridge_GetDefaultContentSetting( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type) { |
| return GetHostContentSettingsMap(jbrowser_context_handle) |
| ->GetDefaultContentSetting( |
| static_cast<ContentSettingsType>(content_settings_type), nullptr); |
| } |
| |
| static void JNI_WebsitePreferenceBridge_SetDefaultContentSetting( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type, |
| int setting) { |
| GetHostContentSettingsMap(jbrowser_context_handle) |
| ->SetDefaultContentSetting( |
| static_cast<ContentSettingsType>(content_settings_type), |
| static_cast<ContentSetting>(setting)); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsContentSettingUserModifiable( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type) { |
| return IsContentSettingUserModifiable( |
| jbrowser_context_handle, |
| static_cast<ContentSettingsType>(content_settings_type)); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_IsContentSettingManagedByCustodian( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle, |
| int content_settings_type) { |
| return IsContentSettingManagedByCustodian( |
| jbrowser_context_handle, |
| static_cast<ContentSettingsType>(content_settings_type)); |
| } |
| |
| static jboolean JNI_WebsitePreferenceBridge_GetLocationAllowedByPolicy( |
| JNIEnv* env, |
| const JavaParamRef<jobject>& jbrowser_context_handle) { |
| if (!IsContentSettingManaged(jbrowser_context_handle, |
| ContentSettingsType::GEOLOCATION)) |
| return false; |
| return GetHostContentSettingsMap(jbrowser_context_handle) |
| ->GetDefaultContentSetting(ContentSettingsType::GEOLOCATION, |
| nullptr) == CONTENT_SETTING_ALLOW; |
| } |
| |
| static ScopedJavaLocalRef<jstring> |
| JNI_WebsitePreferenceBridge_ToDomainWildcardPattern( |
| JNIEnv* env, |
| const JavaParamRef<jstring>& pattern) { |
| std::string pattern_string = ConvertJavaStringToUTF8(env, pattern); |
| ContentSettingsPattern original_pattern = |
| ContentSettingsPattern::FromString(pattern_string); |
| ContentSettingsPattern domain_wildcard_pattern = |
| ContentSettingsPattern::ToDomainWildcardPattern(original_pattern); |
| std::string domain_wildcard_pattern_string = |
| domain_wildcard_pattern.IsValid() |
| ? domain_wildcard_pattern.ToString() |
| : ContentSettingsPattern::ToHostOnlyPattern(original_pattern) |
| .ToString(); |
| return ConvertUTF8ToJavaString(env, domain_wildcard_pattern_string); |
| } |
| |
| static ScopedJavaLocalRef<jstring> |
| JNI_WebsitePreferenceBridge_ToHostOnlyPattern( |
| JNIEnv* env, |
| const JavaParamRef<jstring>& pattern) { |
| std::string pattern_string = ConvertJavaStringToUTF8(env, pattern); |
| ContentSettingsPattern host_only_pattern = |
| ContentSettingsPattern::ToHostOnlyPattern( |
| ContentSettingsPattern::FromString(pattern_string)); |
| return ConvertUTF8ToJavaString(env, host_only_pattern.ToString()); |
| } |