diff --git a/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt b/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
index f5ea619e403..bf8f84d52e9 100644
--- a/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
+++ b/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
@@ -21,6 +21,7 @@ import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY_INAUDIBLE
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_GEOLOCATION
+import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_MEDIA_KEY_SYSTEM_ACCESS
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_PERSISTENT_STORAGE
import java.util.UUID
@@ -59,7 +60,8 @@ sealed class GeckoPermissionRequest constructor(
PERMISSION_GEOLOCATION to Permission.ContentGeoLocation(),
PERMISSION_AUTOPLAY_AUDIBLE to Permission.ContentAutoPlayAudible(),
PERMISSION_AUTOPLAY_INAUDIBLE to Permission.ContentAutoPlayInaudible(),
- PERMISSION_PERSISTENT_STORAGE to Permission.ContentPersistentStorage()
+ PERMISSION_PERSISTENT_STORAGE to Permission.ContentPersistentStorage(),
+ PERMISSION_MEDIA_KEY_SYSTEM_ACCESS to Permission.ContentMediaKeySystemAccess()
)
}
}
diff --git a/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt b/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
index f5ea619e403..bf8f84d52e9 100644
--- a/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
+++ b/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
@@ -21,6 +21,7 @@ import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY_INAUDIBLE
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_GEOLOCATION
+import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_MEDIA_KEY_SYSTEM_ACCESS
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_PERSISTENT_STORAGE
import java.util.UUID
@@ -59,7 +60,8 @@ sealed class GeckoPermissionRequest constructor(
PERMISSION_GEOLOCATION to Permission.ContentGeoLocation(),
PERMISSION_AUTOPLAY_AUDIBLE to Permission.ContentAutoPlayAudible(),
PERMISSION_AUTOPLAY_INAUDIBLE to Permission.ContentAutoPlayInaudible(),
- PERMISSION_PERSISTENT_STORAGE to Permission.ContentPersistentStorage()
+ PERMISSION_PERSISTENT_STORAGE to Permission.ContentPersistentStorage(),
+ PERMISSION_MEDIA_KEY_SYSTEM_ACCESS to Permission.ContentMediaKeySystemAccess()
)
}
}
diff --git a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
index f5ea619e403..bf8f84d52e9 100644
--- a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
+++ b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/permission/GeckoPermissionRequest.kt
@@ -21,6 +21,7 @@ import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_AUTOPLAY_INAUDIBLE
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_GEOLOCATION
+import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_MEDIA_KEY_SYSTEM_ACCESS
import org.mozilla.geckoview.GeckoSession.PermissionDelegate.PERMISSION_PERSISTENT_STORAGE
import java.util.UUID
@@ -59,7 +60,8 @@ sealed class GeckoPermissionRequest constructor(
PERMISSION_GEOLOCATION to Permission.ContentGeoLocation(),
PERMISSION_AUTOPLAY_AUDIBLE to Permission.ContentAutoPlayAudible(),
PERMISSION_AUTOPLAY_INAUDIBLE to Permission.ContentAutoPlayInaudible(),
- PERMISSION_PERSISTENT_STORAGE to Permission.ContentPersistentStorage()
+ PERMISSION_PERSISTENT_STORAGE to Permission.ContentPersistentStorage(),
+ PERMISSION_MEDIA_KEY_SYSTEM_ACCESS to Permission.ContentMediaKeySystemAccess()
)
}
}
diff --git a/components/concept/engine/src/main/java/mozilla/components/concept/engine/permission/PermissionRequest.kt b/components/concept/engine/src/main/java/mozilla/components/concept/engine/permission/PermissionRequest.kt
index a52af746f55..6c7d20b6851 100644
--- a/components/concept/engine/src/main/java/mozilla/components/concept/engine/permission/PermissionRequest.kt
+++ b/components/concept/engine/src/main/java/mozilla/components/concept/engine/permission/PermissionRequest.kt
@@ -80,6 +80,8 @@ sealed class Permission {
data class ContentAutoPlayAudible(override val id: String? = "", override val desc: String? = "") : Permission()
data class ContentAutoPlayInaudible(override val id: String? = "", override val desc: String? = "") : Permission()
data class ContentPersistentStorage(override val id: String? = "", override val desc: String? = "") : Permission()
+ data class ContentMediaKeySystemAccess(override val id: String? = "", override val desc: String? = "") :
+ Permission()
data class AppCamera(override val id: String? = "", override val desc: String? = "") : Permission()
data class AppAudio(override val id: String? = "", override val desc: String? = "") : Permission()
diff --git a/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/4.json b/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/4.json
new file mode 100644
index 00000000000..f91ee575159
--- /dev/null
+++ b/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/4.json
@@ -0,0 +1,94 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 4,
+ "identityHash": "f5379c8eb4f1519eb5994e508626ca10",
+ "entities": [
+ {
+ "tableName": "site_permissions",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `location` INTEGER NOT NULL, `notification` INTEGER NOT NULL, `microphone` INTEGER NOT NULL, `camera` INTEGER NOT NULL, `bluetooth` INTEGER NOT NULL, `local_storage` INTEGER NOT NULL, `autoplay_audible` INTEGER NOT NULL, `autoplay_inaudible` INTEGER NOT NULL, `media_key_system_access` INTEGER NOT NULL, `saved_at` INTEGER NOT NULL, PRIMARY KEY(`origin`))",
+ "fields": [
+ {
+ "fieldPath": "origin",
+ "columnName": "origin",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "location",
+ "columnName": "location",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "notification",
+ "columnName": "notification",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "microphone",
+ "columnName": "microphone",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "camera",
+ "columnName": "camera",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "bluetooth",
+ "columnName": "bluetooth",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "localStorage",
+ "columnName": "local_storage",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "autoplayAudible",
+ "columnName": "autoplay_audible",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "autoplayInaudible",
+ "columnName": "autoplay_inaudible",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "mediaKeySystemAccess",
+ "columnName": "media_key_system_access",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "savedAt",
+ "columnName": "saved_at",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "origin"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f5379c8eb4f1519eb5994e508626ca10')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt b/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt
index cc217a2dde8..4f8f1e9eae7 100644
--- a/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt
+++ b/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt
@@ -127,4 +127,29 @@ class OnDeviceSitePermissionsStorageTest {
assertEquals(Status.ALLOWED.id, cursor.getInt(cursor.getColumnIndexOrThrow("autoplay_inaudible")))
}
}
+
+ @Test
+ fun migrate3to4() {
+ helper.createDatabase(MIGRATION_TEST_DB, 3).apply {
+ query("SELECT * FROM site_permissions").use { cursor ->
+ assertEquals(10, cursor.columnCount)
+ }
+ execSQL(
+ "INSERT INTO " +
+ "site_permissions " +
+ "(origin, location, notification, microphone,camera,bluetooth,local_storage,autoplay_audible,autoplay_inaudible,saved_at) " +
+ "VALUES " +
+ "('mozilla.org',1,1,1,1,1,1,1,1,1)"
+ )
+ }
+
+ val dbVersion3 = helper.runMigrationsAndValidate(MIGRATION_TEST_DB, 4, true, Migrations.migration_3_4)
+
+ dbVersion3.query("SELECT * FROM site_permissions").use { cursor ->
+ assertEquals(11, cursor.columnCount)
+
+ cursor.moveToFirst()
+ assertEquals(Status.NO_DECISION.id, cursor.getInt(cursor.getColumnIndexOrThrow("media_key_system_access")))
+ }
+ }
}
diff --git a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissions.kt b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissions.kt
index e1ab995f68d..b68a44a65be 100644
--- a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissions.kt
+++ b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissions.kt
@@ -23,6 +23,7 @@ data class SitePermissions(
val localStorage: Status = NO_DECISION,
val autoplayAudible: Status = NO_DECISION,
val autoplayInaudible: Status = NO_DECISION,
+ val mediaKeySystemAccess: Status = NO_DECISION,
val savedAt: Long
) : Parcelable {
enum class Status(
@@ -53,6 +54,7 @@ data class SitePermissions(
Permission.LOCATION -> location
Permission.AUTOPLAY_AUDIBLE -> autoplayAudible
Permission.AUTOPLAY_INAUDIBLE -> autoplayInaudible
+ Permission.MEDIA_KEY_SYSTEM_ACCESS -> mediaKeySystemAccess
}
}
}
diff --git a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
index 50c60eb6438..6ff77aa46de 100644
--- a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
+++ b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
@@ -35,6 +35,7 @@ import mozilla.components.concept.engine.permission.Permission.ContentNotificati
import mozilla.components.concept.engine.permission.Permission.ContentVideoCamera
import mozilla.components.concept.engine.permission.Permission.ContentVideoCapture
import mozilla.components.concept.engine.permission.Permission.ContentPersistentStorage
+import mozilla.components.concept.engine.permission.Permission.ContentMediaKeySystemAccess
import mozilla.components.concept.engine.permission.Permission.AppLocationCoarse
import mozilla.components.concept.engine.permission.Permission.AppLocationFine
import mozilla.components.concept.engine.permission.Permission.AppAudio
@@ -438,6 +439,9 @@ class SitePermissionsFeature(
is ContentPersistentStorage -> {
permissionFromStore.localStorage.doNotAskAgain()
}
+ is ContentMediaKeySystemAccess -> {
+ permissionFromStore.mediaKeySystemAccess.doNotAskAgain()
+ }
else -> false
}
}
@@ -499,6 +503,9 @@ class SitePermissionsFeature(
is ContentPersistentStorage -> {
sitePermissions.copy(localStorage = status)
}
+ is ContentMediaKeySystemAccess -> {
+ sitePermissions.copy(mediaKeySystemAccess = status)
+ }
else ->
throw InvalidParameterException("$permission is not a valid permission.")
}
@@ -526,6 +533,7 @@ class SitePermissionsFeature(
}
}
+ @Suppress("LongMethod")
@VisibleForTesting
internal fun handlingSingleContentPermissions(
permissionRequest: PermissionRequest,
@@ -592,6 +600,17 @@ class SitePermissionsFeature(
shouldSelectRememberChoice = true
)
}
+ is ContentMediaKeySystemAccess -> {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_media_key_system_access_title,
+ R.drawable.mozac_ic_link,
+ showDoNotAskAgainCheckBox = false,
+ shouldSelectRememberChoice = true
+ )
+ }
else ->
throw InvalidParameterException("$permission is not a valid permission.")
}
@@ -727,6 +746,9 @@ internal fun isPermissionGranted(
is ContentPersistentStorage -> {
permissionFromStorage.localStorage.isAllowed()
}
+ is ContentMediaKeySystemAccess -> {
+ permissionFromStorage.mediaKeySystemAccess.isAllowed()
+ }
else ->
throw InvalidParameterException("$permission is not a valid permission.")
}
@@ -739,7 +761,8 @@ private fun Permission.isSupported(): Boolean {
is ContentPersistentStorage,
is ContentAudioCapture, is ContentAudioMicrophone,
is ContentVideoCamera, is ContentVideoCapture,
- is ContentAutoPlayAudible, is ContentAutoPlayInaudible -> true
+ is ContentAutoPlayAudible, is ContentAutoPlayInaudible,
+ is ContentMediaKeySystemAccess -> true
else -> false
}
}
diff --git a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt
index 1d5ca18ab34..c89733e54a6 100644
--- a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt
+++ b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt
@@ -19,7 +19,8 @@ data class SitePermissionsRules internal constructor(
val microphone: Action,
val autoplayAudible: Action,
val autoplayInaudible: Action,
- val persistentStorage: Action
+ val persistentStorage: Action,
+ val mediaKeySystemAccess: Action
) {
constructor(
@@ -29,7 +30,8 @@ data class SitePermissionsRules internal constructor(
microphone: Action,
autoplayAudible: AutoplayAction,
autoplayInaudible: AutoplayAction,
- persistentStorage: Action
+ persistentStorage: Action,
+ mediaKeySystemAccess: Action
) : this(
camera = camera,
location = location,
@@ -37,7 +39,8 @@ data class SitePermissionsRules internal constructor(
microphone = microphone,
autoplayAudible = autoplayAudible.toAction(),
autoplayInaudible = autoplayInaudible.toAction(),
- persistentStorage = persistentStorage
+ persistentStorage = persistentStorage,
+ mediaKeySystemAccess = mediaKeySystemAccess
)
enum class Action {
@@ -93,6 +96,9 @@ data class SitePermissionsRules internal constructor(
is Permission.ContentAutoPlayInaudible -> {
autoplayInaudible
}
+ is Permission.ContentMediaKeySystemAccess -> {
+ mediaKeySystemAccess
+ }
else -> ASK_TO_ALLOW
}
}
@@ -118,6 +124,7 @@ data class SitePermissionsRules internal constructor(
autoplayAudible = autoplayAudible.toStatus(),
autoplayInaudible = autoplayInaudible.toStatus(),
localStorage = persistentStorage.toStatus(),
+ mediaKeySystemAccess = mediaKeySystemAccess.toStatus(),
savedAt = savedAt
)
}
diff --git a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsStorage.kt b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsStorage.kt
index 40ed2c2b440..5ea07f71cd6 100644
--- a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsStorage.kt
+++ b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsStorage.kt
@@ -23,6 +23,7 @@ import mozilla.components.feature.sitepermissions.SitePermissionsStorage.Permiss
import mozilla.components.feature.sitepermissions.SitePermissionsStorage.Permission.NOTIFICATION
import mozilla.components.feature.sitepermissions.SitePermissionsStorage.Permission.AUTOPLAY_AUDIBLE
import mozilla.components.feature.sitepermissions.SitePermissionsStorage.Permission.AUTOPLAY_INAUDIBLE
+import mozilla.components.feature.sitepermissions.SitePermissionsStorage.Permission.MEDIA_KEY_SYSTEM_ACCESS
import mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase
import mozilla.components.feature.sitepermissions.db.toSitePermissionsEntity
@@ -116,6 +117,7 @@ class SitePermissionsStorage(
map.putIfAllowed(LOCATION, location, permission)
map.putIfAllowed(AUTOPLAY_AUDIBLE, autoplayAudible, permission)
map.putIfAllowed(AUTOPLAY_INAUDIBLE, autoplayInaudible, permission)
+ map.putIfAllowed(MEDIA_KEY_SYSTEM_ACCESS, mediaKeySystemAccess, permission)
}
}
return map
@@ -173,6 +175,6 @@ class SitePermissionsStorage(
enum class Permission {
MICROPHONE, BLUETOOTH, CAMERA, LOCAL_STORAGE, NOTIFICATION, LOCATION, AUTOPLAY_AUDIBLE,
- AUTOPLAY_INAUDIBLE
+ AUTOPLAY_INAUDIBLE, MEDIA_KEY_SYSTEM_ACCESS
}
}
diff --git a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt
index d46e28c62e3..285c5e2156b 100644
--- a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt
+++ b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt
@@ -17,7 +17,7 @@ import mozilla.components.feature.sitepermissions.SitePermissions
/**
* Internal database for saving site permissions.
*/
-@Database(entities = [SitePermissionsEntity::class], version = 3)
+@Database(entities = [SitePermissionsEntity::class], version = 4)
@TypeConverters(StatusConverter::class)
internal abstract class SitePermissionsDatabase : RoomDatabase() {
abstract fun sitePermissionsDao(): SitePermissionsDao
@@ -38,6 +38,8 @@ internal abstract class SitePermissionsDatabase : RoomDatabase() {
Migrations.migration_1_2
).addMigrations(
Migrations.migration_2_3
+ ).addMigrations(
+ Migrations.migration_3_4
).build().also { instance = it }
}
}
@@ -98,4 +100,17 @@ internal object Migrations {
}
}
}
+
+ @Suppress("MagicNumber")
+ val migration_3_4 = object : Migration(3, 4) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ val hasEmeColumn = database.query("SELECT * FROM site_permissions").columnCount == 11
+ if (!hasEmeColumn) {
+ database.execSQL(
+ "ALTER TABLE site_permissions ADD COLUMN media_key_system_access INTEGER NOT NULL DEFAULT 0")
+ // default is NO_DECISION
+ database.execSQL("UPDATE site_permissions SET media_key_system_access = 0")
+ }
+ }
+ }
}
diff --git a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt
index a244cdf8ecb..6d55c7ad5c1 100644
--- a/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt
+++ b/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt
@@ -43,6 +43,9 @@ internal data class SitePermissionsEntity(
@ColumnInfo(name = "autoplay_inaudible")
var autoplayInaudible: SitePermissions.Status,
+ @ColumnInfo(name = "media_key_system_access")
+ var mediaKeySystemAccess: SitePermissions.Status,
+
@ColumnInfo(name = "saved_at")
var savedAt: Long
) {
@@ -58,6 +61,7 @@ internal data class SitePermissionsEntity(
localStorage,
autoplayAudible,
autoplayInaudible,
+ mediaKeySystemAccess,
savedAt
)
}
@@ -74,6 +78,7 @@ internal fun SitePermissions.toSitePermissionsEntity(): SitePermissionsEntity {
localStorage,
autoplayAudible,
autoplayInaudible,
+ mediaKeySystemAccess,
savedAt
)
}
diff --git a/components/feature/sitepermissions/src/main/res/values/strings.xml b/components/feature/sitepermissions/src/main/res/values/strings.xml
index f0bcabbc64e..3211942fd20 100644
--- a/components/feature/sitepermissions/src/main/res/values/strings.xml
+++ b/components/feature/sitepermissions/src/main/res/values/strings.xml
@@ -36,4 +36,6 @@
Never
Allow %1$s to store data in persistent storage?
-
\ No newline at end of file
+
+ Allow %1$s to play DRM-controlled content?
+
diff --git a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt
index 2075f58edbb..f188098a102 100644
--- a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt
+++ b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt
@@ -772,7 +772,8 @@ class SitePermissionsFeatureTest {
microphone = SitePermissionsRules.Action.BLOCKED,
autoplayAudible = SitePermissionsRules.Action.BLOCKED,
autoplayInaudible = SitePermissionsRules.Action.ALLOWED,
- persistentStorage = SitePermissionsRules.Action.BLOCKED
+ persistentStorage = SitePermissionsRules.Action.BLOCKED,
+ mediaKeySystemAccess = SitePermissionsRules.Action.ASK_TO_ALLOW
)
sitePermissionFeature.sitePermissionsRules = rules
@@ -787,6 +788,7 @@ class SitePermissionsFeatureTest {
assertEquals(BLOCKED, sitePermissions.autoplayAudible)
assertEquals(ALLOWED, sitePermissions.autoplayInaudible)
assertEquals(BLOCKED, sitePermissions.localStorage)
+ assertEquals(NO_DECISION, sitePermissions.mediaKeySystemAccess)
}
@Test
diff --git a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt
index 23799c1169a..83d909d5db9 100644
--- a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt
+++ b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt
@@ -59,7 +59,8 @@ class SitePermissionsRulesTest {
microphone = BLOCKED,
autoplayAudible = ASK_TO_ALLOW,
autoplayInaudible = BLOCKED,
- persistentStorage = BLOCKED
+ persistentStorage = BLOCKED,
+ mediaKeySystemAccess = ASK_TO_ALLOW
)
val mockRequest: PermissionRequest = mock()
@@ -95,6 +96,10 @@ class SitePermissionsRulesTest {
doReturn(listOf(Permission.ContentPersistentStorage())).`when`(mockRequest).permissions
action = rules.getActionFrom(mockRequest)
assertEquals(action, rules.persistentStorage)
+
+ doReturn(listOf(Permission.ContentMediaKeySystemAccess())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.mediaKeySystemAccess)
}
@Test
@@ -106,7 +111,8 @@ class SitePermissionsRulesTest {
notification = ASK_TO_ALLOW,
microphone = BLOCKED,
autoplayInaudible = ASK_TO_ALLOW,
- autoplayAudible = ASK_TO_ALLOW
+ autoplayAudible = ASK_TO_ALLOW,
+ mediaKeySystemAccess = ASK_TO_ALLOW
)
val mockRequest: PermissionRequest = mock()
@@ -122,7 +128,8 @@ class SitePermissionsRulesTest {
microphone = ASK_TO_ALLOW,
autoplayInaudible = BLOCKED,
autoplayAudible = BLOCKED,
- persistentStorage = BLOCKED
+ persistentStorage = BLOCKED,
+ mediaKeySystemAccess = ASK_TO_ALLOW
)
action = rules.getActionFrom(mockRequest)
@@ -140,6 +147,7 @@ class SitePermissionsRulesTest {
microphone = Status.BLOCKED,
autoplayInaudible = Status.NO_DECISION,
autoplayAudible = Status.NO_DECISION,
+ mediaKeySystemAccess = Status.BLOCKED,
savedAt = 1L
)
@@ -150,7 +158,8 @@ class SitePermissionsRulesTest {
microphone = BLOCKED,
autoplayInaudible = ASK_TO_ALLOW,
autoplayAudible = ASK_TO_ALLOW,
- persistentStorage = BLOCKED
+ persistentStorage = BLOCKED,
+ mediaKeySystemAccess = BLOCKED
)
val convertedSitePermissions = rules.toSitePermissions(origin = "origin", savedAt = 1L)
@@ -163,6 +172,7 @@ class SitePermissionsRulesTest {
assertEquals(expectedSitePermission.autoplayInaudible, convertedSitePermissions.autoplayInaudible)
assertEquals(expectedSitePermission.autoplayAudible, convertedSitePermissions.autoplayAudible)
assertEquals(expectedSitePermission.localStorage, convertedSitePermissions.localStorage)
+ assertEquals(expectedSitePermission.mediaKeySystemAccess, convertedSitePermissions.mediaKeySystemAccess)
assertEquals(expectedSitePermission.savedAt, convertedSitePermissions.savedAt)
}
}
diff --git a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsStorageTest.kt b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsStorageTest.kt
index 1d655704ddd..dfc190fefca 100644
--- a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsStorageTest.kt
+++ b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsStorageTest.kt
@@ -162,6 +162,7 @@ class SitePermissionsStorageTest {
bluetooth = ALLOWED,
autoplayAudible = BLOCKED,
autoplayInaudible = NO_DECISION,
+ mediaKeySystemAccess = NO_DECISION,
savedAt = 0
),
SitePermissionsEntity(
@@ -174,6 +175,7 @@ class SitePermissionsStorageTest {
bluetooth = ALLOWED,
autoplayAudible = BLOCKED,
autoplayInaudible = NO_DECISION,
+ mediaKeySystemAccess = NO_DECISION,
savedAt = 0
)
)
diff --git a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt
index 675a7bfb54d..22de388a37a 100644
--- a/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt
+++ b/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt
@@ -25,6 +25,7 @@ class SitePermissionEntityTest {
bluetooth = ALLOWED,
autoplayInaudible = BLOCKED,
autoplayAudible = NO_DECISION,
+ mediaKeySystemAccess = NO_DECISION,
savedAt = 0
)
@@ -40,6 +41,7 @@ class SitePermissionEntityTest {
assertEquals(bluetooth, domainClass.bluetooth)
assertEquals(autoplayAudible, domainClass.autoplayAudible)
assertEquals(autoplayInaudible, domainClass.autoplayInaudible)
+ assertEquals(mediaKeySystemAccess, domainClass.mediaKeySystemAccess)
assertEquals(savedAt, domainClass.savedAt)
}
}
@@ -54,6 +56,9 @@ class SitePermissionEntityTest {
microphone = NO_DECISION,
camera = NO_DECISION,
bluetooth = ALLOWED,
+ autoplayInaudible = BLOCKED,
+ autoplayAudible = NO_DECISION,
+ mediaKeySystemAccess = NO_DECISION,
savedAt = 0
)
@@ -67,6 +72,9 @@ class SitePermissionEntityTest {
assertEquals(microphone, domainClass.microphone)
assertEquals(camera, domainClass.camera)
assertEquals(bluetooth, domainClass.bluetooth)
+ assertEquals(autoplayAudible, domainClass.autoplayAudible)
+ assertEquals(autoplayInaudible, domainClass.autoplayInaudible)
+ assertEquals(mediaKeySystemAccess, domainClass.mediaKeySystemAccess)
assertEquals(savedAt, domainClass.savedAt)
}
}
diff --git a/docs/changelog.md b/docs/changelog.md
index 4c4fa2d82d2..74ece79520a 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -28,6 +28,10 @@ permalink: /changelog/
* **browser-menu**:
* 🚒 Bug fixed [issue #9101](https://github.com/mozilla-mobile/android-components/issues/9101) - Fix BrowserMenu position after rotating the screen on Android <=23
+* **feature-sitepermissions**
+ * ⚠️ **This is a breaking change**: The `SitePermissionsRules` constructor, now requires a new parameter `mediaKeySystemAccess`.
+ * 🌟 Added support for EME permission prompts, see [#7121](https://github.com/mozilla-mobile/android-components/issues/7121).
+
# 68.0.0
* [Commits](https://github.com/mozilla-mobile/android-components/compare/v67.0.0...v68.0.0)
diff --git a/samples/browser/src/main/java/org/mozilla/samples/browser/BaseBrowserFragment.kt b/samples/browser/src/main/java/org/mozilla/samples/browser/BaseBrowserFragment.kt
index 113fc9a25b0..db1d61b8618 100644
--- a/samples/browser/src/main/java/org/mozilla/samples/browser/BaseBrowserFragment.kt
+++ b/samples/browser/src/main/java/org/mozilla/samples/browser/BaseBrowserFragment.kt
@@ -154,7 +154,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler {
location = SitePermissionsRules.Action.ASK_TO_ALLOW,
notification = SitePermissionsRules.Action.ASK_TO_ALLOW,
microphone = SitePermissionsRules.Action.ASK_TO_ALLOW,
- persistentStorage = SitePermissionsRules.Action.ASK_TO_ALLOW
+ persistentStorage = SitePermissionsRules.Action.ASK_TO_ALLOW,
+ mediaKeySystemAccess = SitePermissionsRules.Action.ASK_TO_ALLOW
),
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_APP_PERMISSIONS)