media: Update protected media identifier setting/permission

When per-origin provisioning is not available, set the default setting
for "protected media identifier" from "ALLOW" to "ASK". Also update the
infobar text for this case. See Bug for more context.

Bug: 904883
Test: Manually tested on Android L and Android O.
Change-Id: I7de895b592b06806330c90a2a6d0b32591dc4cb4
Reviewed-on: https://chromium-review.googlesource.com/c/1343342
Reviewed-by: Finnur Thorarinsson <finnur@chromium.org>
Reviewed-by: Balazs Engedy <engedy@chromium.org>
Reviewed-by: Raymes Khoury <raymes@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#617864}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingsResources.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingsResources.java
index ff8ccfa..cfd6027 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingsResources.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSettingsResources.java
@@ -8,6 +8,7 @@
 import android.content.res.Resources;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.support.annotation.Nullable;
 
 import org.chromium.base.ApiCompatibilityUtils;
@@ -359,10 +360,21 @@
      */
     public static int[] getTriStateSettingDescriptionIDs(int contentType) {
         if (contentType == ContentSettingsType.CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) {
-            int[] descriptionIDs = {R.string.website_settings_category_protected_content_allowed,
-                    R.string.website_settings_category_protected_content_ask,
-                    R.string.website_settings_category_protected_content_blocked};
-            return descriptionIDs;
+            // The recommended setting is different on different android versions depending on
+            // whether per-origin provisioning is available. See https://crbug.com/904883.
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                int[] descriptionIDs = {
+                        R.string.website_settings_category_protected_content_allowed_recommended,
+                        R.string.website_settings_category_protected_content_ask,
+                        R.string.website_settings_category_protected_content_blocked};
+                return descriptionIDs;
+            } else {
+                int[] descriptionIDs = {
+                        R.string.website_settings_category_protected_content_allowed,
+                        R.string.website_settings_category_protected_content_ask_recommended,
+                        R.string.website_settings_category_protected_content_blocked};
+                return descriptionIDs;
+            }
         }
 
         assert false;
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index fbf0071..31c0efd 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1017,9 +1017,15 @@
       <message name="IDS_WEBSITE_SETTINGS_CATEGORY_CLIPBOARD_BLOCKED_LIST" desc="Summary text explaining that the clipboard permission is set to block read access on some sites. To be shown in the list of permission categories.">
         Blocked from reading clipboard
       </message>
-      <message name="IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED" desc="Summary text explaining that sites are allowed to play protected content and that it is the recommended setting.">
+      <message name="IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED_RECOMMENDED" desc="Summary text explaining that sites are allowed to play protected content and that it is the recommended setting.">
         Allow sites to play protected content (recommended)
       </message>
+      <message name="IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED" desc="Summary text explaining that sites are allowed to play protected content.">
+        Allow sites to play protected content
+      </message>
+      <message name="IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ASK_RECOMMENDED" desc="Summary text explaining that sites need to ask for permission before playing protected content and that it is the recommended setting.">
+        Ask before allowing sites to play protected content (recommended)
+      </message>
       <message name="IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ASK" desc="Summary text explaining that sites need to ask for permission before playing protected content.">
         Ask before allowing sites to play protected content
       </message>
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED.png.sha1
index 1b23859..a2f9901 100644
--- a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED.png.sha1
+++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED.png.sha1
@@ -1 +1 @@
-e8943113528b0aab722fe4d777832797a5f2e35a
\ No newline at end of file
+1c4b0186b4be157c61bf2d1e56b12102627c0218
\ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED_RECOMMENDED.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED_RECOMMENDED.png.sha1
new file mode 100644
index 0000000..fd053e5
--- /dev/null
+++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ALLOWED_RECOMMENDED.png.sha1
@@ -0,0 +1 @@
+74913771c6f31ecb202842ac0e430594f2135c55
\ No newline at end of file
diff --git a/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ASK_RECOMMENDED.png.sha1 b/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ASK_RECOMMENDED.png.sha1
new file mode 100644
index 0000000..1d75ed02
--- /dev/null
+++ b/chrome/android/java/strings/android_chrome_strings_grd/IDS_WEBSITE_SETTINGS_CATEGORY_PROTECTED_CONTENT_ASK_RECOMMENDED.png.sha1
@@ -0,0 +1 @@
+e97f3e55f43fe40d0d8615543e18e63f6e3144fc
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d47500f..4c1e6b3 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7884,9 +7884,12 @@
         <message name="IDS_PROTECTED_MEDIA_IDENTIFIER_PERMISSION_FRAGMENT" desc="Permission fragment shown in the permissions bubble when a web page requests access to the computer's protected media identifier.">
           Know your unique device identifier
         </message>
-        <message name="IDS_PROTECTED_MEDIA_IDENTIFIER_INFOBAR_TEXT" desc="Text requesting permission for a site to access protected media identifier. It shows the origin of the URL.">
+        <message name="IDS_PROTECTED_MEDIA_IDENTIFIER_PER_ORIGIN_PROVISIONING_INFOBAR_TEXT" desc="Text requesting permission for a site to access protected media identifier. It shows the origin of the URL.">
           <ph name="URL">$1<ex>https://www.youtube.com</ex></ph> wants to play protected content. Your device’s identity will be verified by Google.
         </message>
+        <message name="IDS_PROTECTED_MEDIA_IDENTIFIER_PER_DEVICE_PROVISIONING_INFOBAR_TEXT" desc="Text requesting permission for a site to access protected media identifier. It shows the origin of the URL.">
+          <ph name="URL">$1<ex>https://www.youtube.com</ex></ph> wants to play protected content. Your device's identity will be verified by Google and may be accessed by this site.
+        </message>
       </if>
       <message name="IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TEXT" desc="A message that the browser shows after saving a password it has autogenerated for the user. This message appears in a bubble and contains a link to all the user's saved autogenerated passwords. The link text is a separate string in the translation console and appears here as placeholder text.">
         View and manage saved passwords in your <ph name="SAVED_PASSWORDS_STORE">$1<ex>Google Account</ex></ph>
diff --git a/chrome/app/generated_resources_grd/IDS_PROTECTED_MEDIA_IDENTIFIER_PER_DEVICE_PROVISIONING_INFOBAR_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_PROTECTED_MEDIA_IDENTIFIER_PER_DEVICE_PROVISIONING_INFOBAR_TEXT.png.sha1
new file mode 100644
index 0000000..a71290f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_PROTECTED_MEDIA_IDENTIFIER_PER_DEVICE_PROVISIONING_INFOBAR_TEXT.png.sha1
@@ -0,0 +1 @@
+9bdd8ad34fe7ce26f5d5f0325a42bada2b559d0c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_PROTECTED_MEDIA_IDENTIFIER_PER_ORIGIN_PROVISIONING_INFOBAR_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_PROTECTED_MEDIA_IDENTIFIER_PER_ORIGIN_PROVISIONING_INFOBAR_TEXT.png.sha1
new file mode 100644
index 0000000..4131dd1
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_PROTECTED_MEDIA_IDENTIFIER_PER_ORIGIN_PROVISIONING_INFOBAR_TEXT.png.sha1
@@ -0,0 +1 @@
+c636d8f77888d8d20f71b8fb9272282230f12531
\ No newline at end of file
diff --git a/chrome/browser/permissions/permission_manager_unittest.cc b/chrome/browser/permissions/permission_manager_unittest.cc
index 6fdf63e6..ab0513f 100644
--- a/chrome/browser/permissions/permission_manager_unittest.cc
+++ b/chrome/browser/permissions/permission_manager_unittest.cc
@@ -30,6 +30,7 @@
 #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h"
 
 #if defined(OS_ANDROID)
+#include "base/android/build_info.h"
 #include "chrome/browser/android/chrome_feature_list.h"
 #include "chrome/browser/android/mock_location_settings.h"
 #include "chrome/browser/geolocation/geolocation_permission_context_android.h"
@@ -52,6 +53,23 @@
   DISALLOW_COPY_AND_ASSIGN(PermissionManagerTestingProfile);
 };
 
+#if defined(OS_ANDROID)
+// See https://crbug.com/904883.
+auto GetDefaultProtectedMediaIdentifierPermissionStatus() {
+  return base::android::BuildInfo::GetInstance()->sdk_int() >=
+                 base::android::SDK_VERSION_MARSHMALLOW
+             ? PermissionStatus::GRANTED
+             : PermissionStatus::ASK;
+}
+
+auto GetDefaultProtectedMediaIdentifierContentSetting() {
+  return base::android::BuildInfo::GetInstance()->sdk_int() >=
+                 base::android::SDK_VERSION_MARSHMALLOW
+             ? CONTENT_SETTING_ALLOW
+             : CONTENT_SETTING_ASK;
+}
+#endif  // defined(OS_ANDROID)
+
 }  // namespace
 
 class PermissionManagerTest : public ChromeRenderViewHostTestHarness {
@@ -208,7 +226,7 @@
   CheckPermissionStatus(PermissionType::GEOLOCATION, PermissionStatus::ASK);
 #if defined(OS_ANDROID)
   CheckPermissionStatus(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
-                        PermissionStatus::GRANTED);
+                        GetDefaultProtectedMediaIdentifierPermissionStatus());
 #endif
 }
 
@@ -241,7 +259,7 @@
                         PermissionStatusSource::UNSPECIFIED);
 #if defined(OS_ANDROID)
   CheckPermissionResult(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
-                        CONTENT_SETTING_ALLOW,
+                        GetDefaultProtectedMediaIdentifierContentSetting(),
                         PermissionStatusSource::UNSPECIFIED);
 #endif
 }
diff --git a/chrome/browser/permissions/permission_request_impl.cc b/chrome/browser/permissions/permission_request_impl.cc
index a716bb8..d4a744b 100644
--- a/chrome/browser/permissions/permission_request_impl.cc
+++ b/chrome/browser/permissions/permission_request_impl.cc
@@ -13,6 +13,7 @@
 
 #if defined(OS_ANDROID)
 #include "chrome/browser/android/android_theme_resources.h"
+#include "media/base/android/media_drm_bridge.h"
 #else
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "components/vector_icons/vector_icons.h"
@@ -102,7 +103,10 @@
       message_id = IDS_MIDI_SYSEX_INFOBAR_TEXT;
       break;
     case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
-      message_id = IDS_PROTECTED_MEDIA_IDENTIFIER_INFOBAR_TEXT;
+      message_id =
+          media::MediaDrmBridge::IsPerOriginProvisioningSupported()
+              ? IDS_PROTECTED_MEDIA_IDENTIFIER_PER_ORIGIN_PROVISIONING_INFOBAR_TEXT
+              : IDS_PROTECTED_MEDIA_IDENTIFIER_PER_DEVICE_PROVISIONING_INFOBAR_TEXT;
       break;
     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
       message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_INFOBAR_TEXT;
diff --git a/components/content_settings/core/browser/BUILD.gn b/components/content_settings/core/browser/BUILD.gn
index 6484333..8e6d992b 100644
--- a/components/content_settings/core/browser/BUILD.gn
+++ b/components/content_settings/core/browser/BUILD.gn
@@ -62,6 +62,10 @@
     "//url",
   ]
 
+  if (is_android) {
+    deps += [ "//media" ]
+  }
+
   configs += [
     "//build/config/compiler:no_size_t_to_int_warning",
     "//build/config/compiler:wexit_time_destructors",
diff --git a/components/content_settings/core/browser/DEPS b/components/content_settings/core/browser/DEPS
index 1cd4d4e..747e920 100644
--- a/components/content_settings/core/browser/DEPS
+++ b/components/content_settings/core/browser/DEPS
@@ -6,6 +6,7 @@
   "+components/sync_preferences",
   "+components/url_formatter",
   "+extensions/buildflags",
+  "+media/base/android",
   "+net/base",
   "+net/cookies",
   "+services/preferences/public",
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc
index f7caa64..4924d2c 100644
--- a/components/content_settings/core/browser/content_settings_registry.cc
+++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -16,6 +16,10 @@
 #include "components/content_settings/core/browser/website_settings_registry.h"
 #include "components/content_settings/core/common/content_settings.h"
 
+#if defined(OS_ANDROID)
+#include "media/base/android/media_drm_bridge.h"
+#endif
+
 namespace content_settings {
 
 namespace {
@@ -68,6 +72,19 @@
   return std::set<ContentSetting>(settings, settings + arraysize(settings));
 }
 
+ContentSetting GetInitialDefaultContentSettingForProtectedMediaIdentifier() {
+// On Android, the default value is ALLOW or ASK depending on whether per-origin
+// provisioning is used (https://crbug.com/854737 and https://crbug.com/904883).
+// On ChromeOS the default value is always ASK.
+#if defined(OS_ANDROID)
+  return media::MediaDrmBridge::IsPerOriginProvisioningSupported()
+             ? CONTENT_SETTING_ALLOW
+             : CONTENT_SETTING_ASK;
+#else
+  return CONTENT_SETTING_ASK;
+#endif  // defined(OS_ANDROID)
+}
+
 }  // namespace
 
 // static
@@ -264,26 +281,19 @@
            ContentSettingsInfo::PERSISTENT,
            ContentSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY);
 
+  const auto protected_media_identifier_setting =
+      GetInitialDefaultContentSettingForProtectedMediaIdentifier();
   Register(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
-           "protected-media-identifier",
-// On Android, the default value is ALLOW. See https://crbug.com/854737 for
-// details. On ChromeOS the default value is still ASK.
-#if defined(OS_ANDROID)
-           CONTENT_SETTING_ALLOW,
-#else
-           CONTENT_SETTING_ASK,
-#endif  // defined(OS_ANDROID)
+           "protected-media-identifier", protected_media_identifier_setting,
            WebsiteSettingsInfo::UNSYNCABLE, WhitelistedSchemes(),
            ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
                          CONTENT_SETTING_ASK),
            WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE,
            WebsiteSettingsRegistry::PLATFORM_ANDROID |
                WebsiteSettingsRegistry::PLATFORM_CHROMEOS,
-#if defined(OS_ANDROID)
-           ContentSettingsInfo::INHERIT_IN_INCOGNITO,
-#else
-           ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE,
-#endif  // defined(OS_ANDROID)
+           protected_media_identifier_setting == CONTENT_SETTING_ALLOW
+               ? ContentSettingsInfo::INHERIT_IN_INCOGNITO
+               : ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE,
            ContentSettingsInfo::PERSISTENT,
            ContentSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY);
 
diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc
index c576edf..efcde6a6 100644
--- a/media/base/android/media_drm_bridge.cc
+++ b/media/base/android/media_drm_bridge.cc
@@ -264,14 +264,6 @@
   return true;
 }
 
-bool IsPersistentLicenseTypeSupportedByMediaDrm() {
-  return MediaDrmBridge::IsAvailable() &&
-         // In development. See http://crbug.com/493521
-         base::FeatureList::IsEnabled(kMediaDrmPersistentLicense) &&
-         base::android::BuildInfo::GetInstance()->sdk_int() >=
-             base::android::SDK_VERSION_MARSHMALLOW;
-}
-
 }  // namespace
 
 // MediaDrm is not generally usable without MediaCodec. Thus, both the MediaDrm
@@ -290,11 +282,20 @@
 }
 
 // static
+bool MediaDrmBridge::IsPerOriginProvisioningSupported() {
+  return base::android::BuildInfo::GetInstance()->sdk_int() >=
+         base::android::SDK_VERSION_MARSHMALLOW;
+}
+
+// static
 bool MediaDrmBridge::IsPersistentLicenseTypeSupported(
-    const std::string& key_system) {
+    const std::string& /* key_system */) {
   // TODO(yucliu): Check |key_system| if persistent license is supported by
   // MediaDrm.
-  return IsPersistentLicenseTypeSupportedByMediaDrm();
+  return MediaDrmBridge::IsAvailable() &&
+         // In development. See http://crbug.com/493521
+         base::FeatureList::IsEnabled(kMediaDrmPersistentLicense) &&
+         IsPerOriginProvisioningSupported();
 }
 
 // static
@@ -455,7 +456,8 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
   DVLOG(2) << __func__;
 
-  DCHECK(IsPersistentLicenseTypeSupportedByMediaDrm());
+  // Key system is not used, so just pass an empty string here.
+  DCHECK(IsPersistentLicenseTypeSupported(""));
 
   if (session_type != CdmSessionType::kPersistentLicense) {
     promise->reject(
@@ -828,9 +830,8 @@
       // TODO(yucliu): Remove the check once persistent storage is fully
       // supported and check if origin is valid.
       base::FeatureList::IsEnabled(kMediaDrmPersistentLicense) &&
-      // MediaDrm implements origin isolated storage on Marshmallow.
-      base::android::BuildInfo::GetInstance()->sdk_int() >=
-          base::android::SDK_VERSION_MARSHMALLOW &&
+      // Per-origin provisioning must be supported for origin isolated storage.
+      IsPerOriginProvisioningSupported() &&
       // origin id can be empty when MediaDrmBridge is created by
       // CreateWithoutSessionSupport, which is used for unprovisioning.
       !origin_id.empty();
diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h
index 6ee3b98..fd9aff8 100644
--- a/media/base/android/media_drm_bridge.h
+++ b/media/base/android/media_drm_bridge.h
@@ -74,6 +74,10 @@
       const std::string& key_system,
       const std::string& container_mime_type);
 
+  // Whether per-origin provisioning (setting "origin" property on MediaDrm) is
+  // supported or not. If false, per-device provisioning is used.
+  static bool IsPerOriginProvisioningSupported();
+
   static bool IsPersistentLicenseTypeSupported(const std::string& key_system);
 
   // Returns the list of the platform-supported key system names that