summaryrefslogtreecommitdiffstats
path: root/mobile/android/android-components/components/feature/sitepermissions
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/android-components/components/feature/sitepermissions')
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/README.md61
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/build.gradle88
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/proguard-rules.pro21
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/1.json81
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/2.json75
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/3.json88
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/4.json94
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/5.json94
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/6.json94
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/7.json94
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/8.json100
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt230
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDaoTest.kt112
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/AndroidManifest.xml4
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorage.kt194
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt258
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFacts.kt65
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt1057
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt126
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDao.kt40
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt189
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt89
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/layout/mozac_site_permissions_prompt.xml127
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-am/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-an/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ar/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ast/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-az/strings.xml36
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-be/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bg/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bn/strings.xml38
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-br/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bs/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ca/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cak/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ceb/strings.xml38
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ckb/strings.xml38
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-co/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cs/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-da/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-de/strings.xml57
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-dsb/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-el/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rCA/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rGB/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eo/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rAR/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rCL/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rES/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rMX/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-et/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eu/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fa/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ff/strings.xml36
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fi/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fr/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fur/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fy-rNL/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ga-rIE/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gd/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gl/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gn/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gu-rIN/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hi-rIN/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hil/strings.xml6
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hr/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hsb/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hu/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hy-rAM/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ia/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-in/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-is/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-it/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-iw/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ja/strings.xml57
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ka/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kaa/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kab/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kk/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kmr/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kn/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ko/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lij/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lo/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lt/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ml/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-mr/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-my/strings.xml38
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nb-rNO/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ne-rNP/strings.xml46
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nl/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nn-rNO/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-oc/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-or/strings.xml12
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rIN/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rPK/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pl/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rBR/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rPT/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-rm/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ro/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ru/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sat/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sc/strings.xml45
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-si/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sk/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-skr/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sl/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sq/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sr/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-su/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sv-rSE/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ta/strings.xml36
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-te/strings.xml42
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tg/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-th/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tl/strings.xml42
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tr/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-trs/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tt/strings.xml42
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tzm/strings.xml30
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ug/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uk/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ur/strings.xml38
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uz/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vec/strings.xml34
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vi/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-yo/strings.xml48
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rCN/strings.xml57
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rTW/strings.xml57
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/main/res/values/strings.xml51
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorageTest.kt251
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragmentTest.kt481
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFactsTest.kt116
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt1450
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt199
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsTest.kt88
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt86
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/StatusConverterTest.kt72
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker2
-rw-r--r--mobile/android/android-components/components/feature/sitepermissions/src/test/resources/robolectric.properties1
144 files changed, 11149 insertions, 0 deletions
diff --git a/mobile/android/android-components/components/feature/sitepermissions/README.md b/mobile/android/android-components/components/feature/sitepermissions/README.md
new file mode 100644
index 0000000000..5eefdb579c
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/README.md
@@ -0,0 +1,61 @@
+# [Android Components](../../../README.md) > Feature > Site Permissions
+
+A feature for showing site permission request prompts.
+
+## Usage
+
+### Setting up the dependency
+
+Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
+
+```Groovy
+implementation "org.mozilla.components:feature-sitepermissions:{latest-version}"
+```
+
+### SitePermissionsFeature
+
+ ```
+ Add these permissions to your ``AndroidManifest.xml`` file.
+ ```XML
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+ ```
+
+ ```kotlin
+ val onNeedToRequestPermissions : (Array<String>) -> Unit = { permissions ->
+ /* You are in charge of triggering the request for the permissions needed,
+ * this way you can control, when you request the permissions,
+ * in case that you want to show an informative dialog,
+ * to clarify the use of these permissions.
+ */
+ this.requestPermissions(permissions, REQUEST_CODE_APP_PERMISSIONS)
+ }
+
+ val sitePermissionsFeature = SitePermissionsFeature(
+ anchorView = toolbar,
+ sessionManager = components.sessionManager,
+ fragmentManager = requireFragmentManager(),
+ onNeedToRequestPermissions = onNeedToRequestPermissions
+ )
+
+ // It will start listing for new permissionRequest.
+ sitePermissionsFeature.start()
+
+ // It will stop listing for new permissionRequest.
+ sitePermissionsFeature.stop()
+
+
+ // Notify the feature if the permissions requested were granted or rejected.
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
+ when (requestCode) {
+ REQUEST_CODE_APP_PERMISSIONS -> sitePermissionsFeature.onPermissionsResult(grantResults)
+ }
+ }
+
+## License
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/
diff --git a/mobile/android/android-components/components/feature/sitepermissions/build.gradle b/mobile/android/android-components/components/feature/sitepermissions/build.gradle
new file mode 100644
index 0000000000..06fa58246b
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/build.gradle
@@ -0,0 +1,88 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-parcelize'
+
+apply plugin: 'com.google.devtools.ksp'
+
+android {
+ defaultConfig {
+ minSdkVersion config.minSdkVersion
+ compileSdk config.compileSdkVersion
+ targetSdkVersion config.targetSdkVersion
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ ksp {
+ arg("room.schemaLocation", "$projectDir/schemas".toString())
+ arg("room.generateKotlin", "true")
+ }
+
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments += ["room.incremental": "true"]
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ packagingOptions {
+ exclude 'META-INF/proguard/androidx-annotations.pro'
+ }
+
+ sourceSets {
+ androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
+ }
+
+ namespace 'mozilla.components.feature.sitepermissions'
+}
+
+tasks.withType(KotlinCompile).configureEach {
+ kotlinOptions.freeCompilerArgs += "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"
+}
+
+dependencies {
+ implementation project(':browser-state')
+ implementation project(':concept-engine')
+ implementation project(':ui-icons')
+ implementation project(':support-ktx')
+ implementation project(':feature-tabs')
+
+ implementation ComponentsDependencies.kotlin_coroutines
+
+ implementation ComponentsDependencies.androidx_core_ktx
+ implementation ComponentsDependencies.androidx_constraintlayout
+ implementation ComponentsDependencies.androidx_lifecycle_livedata
+ implementation ComponentsDependencies.androidx_paging
+ implementation ComponentsDependencies.androidx_room_runtime
+ ksp ComponentsDependencies.androidx_room_compiler
+
+ testImplementation project(':support-test')
+
+ testImplementation ComponentsDependencies.androidx_test_core
+ testImplementation ComponentsDependencies.androidx_test_junit
+ testImplementation ComponentsDependencies.testing_robolectric
+ testImplementation ComponentsDependencies.testing_coroutines
+
+ androidTestImplementation project(':support-android-test')
+
+ androidTestImplementation ComponentsDependencies.androidx_room_testing
+ androidTestImplementation ComponentsDependencies.androidx_test_core
+ androidTestImplementation ComponentsDependencies.androidx_test_runner
+ androidTestImplementation ComponentsDependencies.androidx_test_rules
+ androidTestImplementation ComponentsDependencies.testing_coroutines
+}
+
+apply from: '../../../android-lint.gradle'
+apply from: '../../../publish.gradle'
+ext.configurePublish(config.componentsGroupId, archivesBaseName, project.ext.description)
diff --git a/mobile/android/android-components/components/feature/sitepermissions/proguard-rules.pro b/mobile/android/android-components/components/feature/sitepermissions/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/1.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/1.json
new file mode 100644
index 0000000000..1363bf43de
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/1.json
@@ -0,0 +1,81 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 1,
+ "identityHash": "462054044d4b7f0e4f80f84380d5cc1e",
+ "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_back` INTEGER NOT NULL, `camera_front` INTEGER NOT NULL, `bluetooth` INTEGER NOT NULL, `local_storage` 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": "cameraBack",
+ "columnName": "camera_back",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "cameraFront",
+ "columnName": "camera_front",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "bluetooth",
+ "columnName": "bluetooth",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "localStorage",
+ "columnName": "local_storage",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "savedAt",
+ "columnName": "saved_at",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "origin"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "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, \"462054044d4b7f0e4f80f84380d5cc1e\")"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/2.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/2.json
new file mode 100644
index 0000000000..344aaccc30
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/2.json
@@ -0,0 +1,75 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 2,
+ "identityHash": "279719818fbc84cac905ddf942282eae",
+ "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, `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": "savedAt",
+ "columnName": "saved_at",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "origin"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "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, \"279719818fbc84cac905ddf942282eae\")"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/3.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/3.json
new file mode 100644
index 0000000000..bfc2906dc9
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/3.json
@@ -0,0 +1,88 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 3,
+ "identityHash": "f5350dbda12da0f415e9d09d00c36f49",
+ "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, `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": "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, 'f5350dbda12da0f415e9d09d00c36f49')"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/4.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/4.json
new file mode 100644
index 0000000000..44e6233c31
--- /dev/null
+++ b/mobile/android/android-components/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')"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/5.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/5.json
new file mode 100644
index 0000000000..c570ac0037
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/5.json
@@ -0,0 +1,94 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 5,
+ "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')"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/6.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/6.json
new file mode 100644
index 0000000000..5780fd467f
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/6.json
@@ -0,0 +1,94 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 6,
+ "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')"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/7.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/7.json
new file mode 100644
index 0000000000..87a2a06f6a
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/7.json
@@ -0,0 +1,94 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 7,
+ "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')"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/8.json b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/8.json
new file mode 100644
index 0000000000..97a9421bd1
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/schemas/mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase/8.json
@@ -0,0 +1,100 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 8,
+ "identityHash": "a4391f9f5b2a6448070c7f5cefb1b086",
+ "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, `cross_origin_storage_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": "crossOriginStorageAccess",
+ "columnName": "cross_origin_storage_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, 'a4391f9f5b2a6448070c7f5cefb1b086')"
+ ]
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt
new file mode 100644
index 0000000000..83b2a5a042
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/OnDeviceSitePermissionsStorageTest.kt
@@ -0,0 +1,230 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions.db
+
+import android.content.Context
+import androidx.core.net.toUri
+import androidx.room.Room
+import androidx.room.testing.MigrationTestHelper
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.platform.app.InstrumentationRegistry
+import kotlinx.coroutines.test.runTest
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status
+import mozilla.components.feature.sitepermissions.OnDiskSitePermissionsStorage
+import mozilla.components.support.ktx.kotlin.getOrigin
+import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+private const val MIGRATION_TEST_DB = "migration-test"
+
+class OnDeviceSitePermissionsStorageTest {
+ private val context: Context
+ get() = ApplicationProvider.getApplicationContext()
+
+ private lateinit var storage: OnDiskSitePermissionsStorage
+ private lateinit var database: SitePermissionsDatabase
+
+ @get:Rule
+ val helper: MigrationTestHelper = MigrationTestHelper(
+ InstrumentationRegistry.getInstrumentation(),
+ SitePermissionsDatabase::class.java,
+ )
+
+ @Before
+ fun setUp() {
+ database = Room.inMemoryDatabaseBuilder(context, SitePermissionsDatabase::class.java).build()
+ storage = OnDiskSitePermissionsStorage(context)
+ storage.databaseInitializer = {
+ database
+ }
+ }
+
+ @After
+ fun tearDown() {
+ database.close()
+ }
+
+ @Test
+ fun testStorageInteraction() = runTest {
+ val origin = "https://www.mozilla.org".toUri().host!!
+ val sitePermissions = SitePermissions(
+ origin = origin,
+ camera = Status.BLOCKED,
+ savedAt = System.currentTimeMillis(),
+ )
+ storage.save(sitePermissions, private = false)
+ val sitePermissionsFromStorage = storage.findSitePermissionsBy(origin, private = false)!!
+
+ assertEquals(origin, sitePermissionsFromStorage.origin)
+ assertEquals(Status.BLOCKED, sitePermissionsFromStorage.camera)
+ }
+
+ @Test
+ fun migrate1to2() {
+ val dbVersion1 = helper.createDatabase(MIGRATION_TEST_DB, 1).apply {
+ execSQL(
+ "INSERT INTO " +
+ "site_permissions " +
+ "(origin, location, notification, microphone,camera_front,camera_back,bluetooth,local_storage,saved_at) " +
+ "VALUES " +
+ "('mozilla.org',1,1,1,1,1,1,1,1)",
+ )
+ }
+
+ dbVersion1.query("SELECT * FROM site_permissions").use { cursor ->
+ assertEquals(9, cursor.columnCount)
+ }
+
+ val dbVersion2 = helper.runMigrationsAndValidate(
+ MIGRATION_TEST_DB,
+ 2,
+ true,
+ Migrations.migration_1_2,
+ ).apply {
+ execSQL(
+ "INSERT INTO " +
+ "site_permissions " +
+ "(origin, location, notification, microphone,camera,bluetooth,local_storage,saved_at) " +
+ "VALUES " +
+ "('mozilla.org',1,1,1,1,1,1,1)",
+ )
+ }
+
+ dbVersion2.query("SELECT * FROM site_permissions").use { cursor ->
+ assertEquals(8, cursor.columnCount)
+
+ cursor.moveToFirst()
+ assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow("camera")))
+ }
+ }
+
+ @Test
+ fun migrate2to3() {
+ helper.createDatabase(MIGRATION_TEST_DB, 2).apply {
+ query("SELECT * FROM site_permissions").use { cursor ->
+ assertEquals(8, cursor.columnCount)
+ }
+ execSQL(
+ "INSERT INTO " +
+ "site_permissions " +
+ "(origin, location, notification, microphone,camera,bluetooth,local_storage,saved_at) " +
+ "VALUES " +
+ "('mozilla.org',1,1,1,1,1,1,1)",
+ )
+ }
+
+ val dbVersion3 = helper.runMigrationsAndValidate(MIGRATION_TEST_DB, 3, true, Migrations.migration_2_3)
+
+ dbVersion3.query("SELECT * FROM site_permissions").use { cursor ->
+ assertEquals(10, cursor.columnCount)
+
+ cursor.moveToFirst()
+ assertEquals(Status.BLOCKED.id, cursor.getInt(cursor.getColumnIndexOrThrow("autoplay_audible")))
+ 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")))
+ }
+ }
+
+ @Test
+ fun migrate4to5() {
+ helper.createDatabase(MIGRATION_TEST_DB, 4).apply {
+ execSQL(
+ "INSERT INTO " +
+ "site_permissions " +
+ "(origin, location, notification, microphone,camera,bluetooth,local_storage,autoplay_audible,autoplay_inaudible,media_key_system_access,saved_at) " +
+ "VALUES " +
+ "('mozilla.org',1,1,1,1,1,1,0,0,1,1)",
+ )
+ }
+
+ val dbVersion5 = helper.runMigrationsAndValidate(MIGRATION_TEST_DB, 5, true, Migrations.migration_4_5)
+
+ dbVersion5.query("SELECT * FROM site_permissions").use { cursor ->
+ cursor.moveToFirst()
+ assertEquals(AutoplayStatus.BLOCKED.id, cursor.getInt(cursor.getColumnIndexOrThrow("autoplay_audible")))
+ assertEquals(AutoplayStatus.ALLOWED.id, cursor.getInt(cursor.getColumnIndexOrThrow("autoplay_inaudible")))
+ }
+ }
+
+ @Test
+ fun migrate5to6() {
+ val url = "https://permission.site/"
+
+ helper.createDatabase(MIGRATION_TEST_DB, 5).apply {
+ execSQL(
+ "INSERT INTO " +
+ "site_permissions " +
+ "(origin, location, notification, microphone,camera,bluetooth,local_storage,autoplay_audible,autoplay_inaudible,media_key_system_access,saved_at) " +
+ "VALUES " +
+ "('${url.tryGetHostFromUrl()}',1,1,1,1,1,1,0,0,1,1)",
+ )
+ }
+
+ val dbVersion6 =
+ helper.runMigrationsAndValidate(MIGRATION_TEST_DB, 6, true, Migrations.migration_5_6)
+
+ dbVersion6.query("SELECT * FROM site_permissions").use { cursor ->
+ cursor.moveToFirst()
+ val urlDB = cursor.getString(cursor.getColumnIndexOrThrow("origin"))
+ assertEquals(url.getOrigin(), urlDB)
+ }
+ }
+
+ @Test
+ fun migrate6to7() {
+ val url = "https://permission.site/"
+
+ helper.createDatabase(MIGRATION_TEST_DB, 6).apply {
+ execSQL(
+ "INSERT INTO " +
+ "site_permissions " +
+ "(origin, location, notification, microphone,camera,bluetooth,local_storage,autoplay_audible,autoplay_inaudible,media_key_system_access,saved_at) " +
+ "VALUES " +
+ "('${url.tryGetHostFromUrl()}',1,1,1,1,1,1,-1,-1,1,1)",
+ ) // Block audio and video.
+ }
+
+ val dbVersion6 =
+ helper.runMigrationsAndValidate(MIGRATION_TEST_DB, 7, true, Migrations.migration_6_7)
+
+ dbVersion6.query("SELECT * FROM site_permissions").use { cursor ->
+ cursor.moveToFirst()
+ val audible = cursor.getInt(cursor.getColumnIndexOrThrow("autoplay_audible"))
+ val inaudible = cursor.getInt(cursor.getColumnIndexOrThrow("autoplay_inaudible"))
+ assertEquals(-1, audible) // Block audio.
+ assertEquals(1, inaudible) // Allow inaudible.
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDaoTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDaoTest.kt
new file mode 100644
index 0000000000..60eba935dd
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/androidTest/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDaoTest.kt
@@ -0,0 +1,112 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions.db
+
+import android.content.Context
+import androidx.core.net.toUri
+import androidx.room.Room
+import androidx.test.core.app.ApplicationProvider
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.BLOCKED
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+
+class SitePermissionsDaoTest {
+
+ private val context: Context
+ get() = ApplicationProvider.getApplicationContext()
+
+ private lateinit var database: SitePermissionsDatabase
+ private lateinit var dao: SitePermissionsDao
+
+ @Before
+ fun setUp() {
+ database = Room.inMemoryDatabaseBuilder(context, SitePermissionsDatabase::class.java).build()
+ dao = database.sitePermissionsDao()
+ }
+
+ @After
+ fun tearDown() {
+ database.close()
+ }
+
+ @Test
+ fun testInsertingAndReadingSitePermissions() {
+ val origin = insertMockSitePermissions("https://www.mozilla.org")
+
+ val siteFromDb = dao.getSitePermissionsBy(origin)!!.toSitePermission()
+
+ assertEquals(origin, siteFromDb.origin)
+ assertEquals(BLOCKED, siteFromDb.camera)
+ assertEquals(AutoplayStatus.BLOCKED, siteFromDb.autoplayAudible)
+ assertEquals(AutoplayStatus.ALLOWED, siteFromDb.autoplayInaudible)
+ }
+
+ @Test
+ fun testRemoveAllSitePermissions() {
+ for (index in 1..4) {
+ val origin = insertMockSitePermissions("https://www.mozilla$index.org")
+
+ val sitePermissionFromDb = dao.getSitePermissionsBy(origin)
+
+ assertEquals(origin, sitePermissionFromDb!!.origin)
+ }
+
+ dao.deleteAllSitePermissions()
+
+ val isEmpty = dao.getSitePermissions().isEmpty()
+
+ assertTrue(isEmpty)
+ }
+
+ @Test
+ fun testUpdateAndDeleteSitePermissions() {
+ val origin = insertMockSitePermissions("https://www.mozilla.org")
+ var siteFromDb = dao.getSitePermissionsBy(origin)!!.toSitePermission()
+
+ assertEquals(BLOCKED, siteFromDb.camera)
+ assertEquals(AutoplayStatus.BLOCKED, siteFromDb.autoplayAudible)
+ assertEquals(AutoplayStatus.ALLOWED, siteFromDb.autoplayInaudible)
+
+ dao.update(
+ siteFromDb.copy(
+ camera = ALLOWED,
+ autoplayInaudible = AutoplayStatus.ALLOWED,
+ autoplayAudible = AutoplayStatus.ALLOWED,
+ ).toSitePermissionsEntity(),
+ )
+
+ siteFromDb = dao.getSitePermissionsBy(origin)!!.toSitePermission()
+
+ assertEquals(ALLOWED, siteFromDb.camera)
+ assertEquals(AutoplayStatus.ALLOWED, siteFromDb.autoplayAudible)
+ assertEquals(AutoplayStatus.ALLOWED, siteFromDb.autoplayInaudible)
+
+ dao.deleteSitePermissions(siteFromDb.toSitePermissionsEntity())
+
+ val notFoundSitePermissions = dao.getSitePermissionsBy(origin)?.toSitePermission()
+
+ assertNull(notFoundSitePermissions)
+ }
+
+ private fun insertMockSitePermissions(url: String): String {
+ val origin = url.toUri().host!!
+ val sitePermissions = SitePermissions(
+ origin = origin,
+ camera = BLOCKED,
+ savedAt = System.currentTimeMillis(),
+ )
+ dao.insert(
+ sitePermissions.toSitePermissionsEntity(),
+ )
+ return origin
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/AndroidManifest.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e16cda1d34
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<manifest />
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorage.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorage.kt
new file mode 100644
index 0000000000..9941761d75
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorage.kt
@@ -0,0 +1,194 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import android.content.Context
+import androidx.annotation.VisibleForTesting
+import androidx.paging.DataSource
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers.Main
+import kotlinx.coroutines.launch
+import mozilla.components.concept.engine.DataCleanable
+import mozilla.components.concept.engine.Engine
+import mozilla.components.concept.engine.Engine.BrowsingData.Companion.PERMISSIONS
+import mozilla.components.concept.engine.permission.PermissionRequest
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.Status
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissionsStorage
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.AUTOPLAY_AUDIBLE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.AUTOPLAY_INAUDIBLE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.BLUETOOTH
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.CAMERA
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.LOCAL_STORAGE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.LOCATION
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.MEDIA_KEY_SYSTEM_ACCESS
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.MICROPHONE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.NOTIFICATION
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.STORAGE_ACCESS
+import mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase
+import mozilla.components.feature.sitepermissions.db.toSitePermissionsEntity
+
+/**
+ * A storage implementation to save [SitePermissions] on disk.
+ */
+class OnDiskSitePermissionsStorage(
+ context: Context,
+ private val dataCleanable: DataCleanable? = null,
+) : SitePermissionsStorage {
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ internal var databaseInitializer = {
+ SitePermissionsDatabase.get(context)
+ }
+
+ private val coroutineScope = CoroutineScope(Main)
+ private val database by lazy { databaseInitializer() }
+
+ /**
+ * Persists the [sitePermissions] provided as a parameter.
+ * @param sitePermissions the [sitePermissions] to be stored.
+ * @param private indicates if the [SitePermissions] belongs to a private session.
+ */
+ override suspend fun save(
+ sitePermissions: SitePermissions,
+ request: PermissionRequest?,
+ private: Boolean,
+ ) {
+ if (private) return // never save private browsing site permissions
+ database
+ .sitePermissionsDao()
+ .insert(
+ sitePermissions.toSitePermissionsEntity(),
+ )
+ }
+
+ /**
+ * Replaces an existing SitePermissions with the values of [sitePermissions] provided as a parameter.
+ * @param sitePermissions the sitePermissions to be updated.
+ * @param private indicates if the [SitePermissions] belongs to a private session.
+ */
+ override suspend fun update(sitePermissions: SitePermissions, private: Boolean) {
+ if (private) return
+ coroutineScope.launch {
+ dataCleanable?.clearData(Engine.BrowsingData.select(PERMISSIONS), sitePermissions.origin)
+ }
+ database.sitePermissionsDao()
+ .update(sitePermissions.toSitePermissionsEntity())
+ }
+
+ /**
+ * Finds all SitePermissions that match the [origin].
+ * @param origin the site to be used as filter in the search.
+ * @param private indicates if the [SitePermissions] belongs to a private session.
+ */
+ override suspend fun findSitePermissionsBy(
+ origin: String,
+ includeTemporary: Boolean,
+ private: Boolean,
+ ): SitePermissions? {
+ if (private) return null
+ return database
+ .sitePermissionsDao()
+ .getSitePermissionsBy(origin)
+ ?.toSitePermission()
+ }
+
+ /**
+ * Returns all saved [SitePermissions] instances as a [DataSource.Factory].
+ *
+ * A consuming app can transform the data source into a `LiveData<PagedList>` of when using RxJava2 into a
+ * `Flowable<PagedList>` or `Observable<PagedList>`, that can be observed.
+ *
+ * - https://developer.android.com/topic/libraries/architecture/paging/data
+ * - https://developer.android.com/topic/libraries/architecture/paging/ui
+ */
+ override suspend fun getSitePermissionsPaged(): DataSource.Factory<Int, SitePermissions> {
+ return database
+ .sitePermissionsDao()
+ .getSitePermissionsPaged()
+ .map { entity ->
+ entity.toSitePermission()
+ }
+ }
+
+ /**
+ * Finds all SitePermissions grouped by [Permission].
+ * @return a map of site grouped by [Permission].
+ */
+ suspend fun findAllSitePermissionsGroupedByPermission(): Map<Permission, List<SitePermissions>> {
+ val sitePermissions = all()
+ val map = mutableMapOf<Permission, MutableList<SitePermissions>>()
+
+ sitePermissions.forEach { permission ->
+ with(permission) {
+ map.putIfAllowed(BLUETOOTH, bluetooth, permission)
+ map.putIfAllowed(MICROPHONE, microphone, permission)
+ map.putIfAllowed(CAMERA, camera, permission)
+ map.putIfAllowed(LOCAL_STORAGE, localStorage, permission)
+ map.putIfAllowed(NOTIFICATION, notification, permission)
+ map.putIfAllowed(LOCATION, location, permission)
+ map.putIfAllowed(AUTOPLAY_AUDIBLE, autoplayAudible.toStatus(), permission)
+ map.putIfAllowed(AUTOPLAY_INAUDIBLE, autoplayInaudible.toStatus(), permission)
+ map.putIfAllowed(MEDIA_KEY_SYSTEM_ACCESS, mediaKeySystemAccess, permission)
+ map.putIfAllowed(STORAGE_ACCESS, crossOriginStorageAccess, permission)
+ }
+ }
+ return map
+ }
+
+ /**
+ * Deletes all sitePermissions that match the sitePermissions provided as a parameter.
+ * @param sitePermissions the sitePermissions to be deleted from the storage.
+ */
+ override suspend fun remove(sitePermissions: SitePermissions, private: Boolean) {
+ coroutineScope.launch {
+ dataCleanable?.clearData(Engine.BrowsingData.select(PERMISSIONS), sitePermissions.origin)
+ }
+ database
+ .sitePermissionsDao()
+ .deleteSitePermissions(
+ sitePermissions.toSitePermissionsEntity(),
+ )
+ }
+
+ /**
+ * Deletes all sitePermissions sitePermissions.
+ */
+ override suspend fun removeAll() {
+ coroutineScope.launch {
+ dataCleanable?.clearData(Engine.BrowsingData.select(PERMISSIONS))
+ }
+ return database
+ .sitePermissionsDao()
+ .deleteAllSitePermissions()
+ }
+
+ /**
+ * Returns all sitePermissions in the store.
+ */
+ override suspend fun all(): List<SitePermissions> {
+ return database
+ .sitePermissionsDao()
+ .getSitePermissions()
+ .map {
+ it.toSitePermission()
+ }
+ }
+
+ private fun MutableMap<Permission, MutableList<SitePermissions>>.putIfAllowed(
+ permission: Permission,
+ status: Status,
+ sitePermissions: SitePermissions,
+ ) {
+ if (status == ALLOWED) {
+ if (this.containsKey(permission)) {
+ this[permission]?.add(sitePermissions)
+ } else {
+ this[permission] = mutableListOf(sitePermissions)
+ }
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt
new file mode 100644
index 0000000000..61a6b10d8b
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt
@@ -0,0 +1,258 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import android.annotation.SuppressLint
+import android.app.Dialog
+import android.content.DialogInterface
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.VISIBLE
+import android.view.ViewGroup
+import android.view.Window
+import android.widget.Button
+import android.widget.CheckBox
+import android.widget.ImageView
+import android.widget.LinearLayout.LayoutParams
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatDialogFragment
+import androidx.core.content.ContextCompat
+
+internal const val KEY_SESSION_ID = "KEY_SESSION_ID"
+internal const val KEY_TITLE = "KEY_TITLE"
+private const val KEY_DIALOG_GRAVITY = "KEY_DIALOG_GRAVITY"
+private const val KEY_DIALOG_WIDTH_MATCH_PARENT = "KEY_DIALOG_WIDTH_MATCH_PARENT"
+private const val KEY_TITLE_ICON = "KEY_TITLE_ICON"
+private const val KEY_MESSAGE = "KEY_MESSAGE"
+private const val KEY_NEGATIVE_BUTTON_TEXT = "KEY_NEGATIVE_BUTTON_TEXT"
+private const val KEY_POSITIVE_BUTTON_BACKGROUND_COLOR = "KEY_POSITIVE_BUTTON_BACKGROUND_COLOR"
+private const val KEY_POSITIVE_BUTTON_TEXT_COLOR = "KEY_POSITIVE_BUTTON_TEXT_COLOR"
+private const val KEY_SHOULD_SHOW_LEARN_MORE_LINK = "KEY_SHOULD_SHOW_LEARN_MORE_LINK"
+private const val KEY_SHOULD_SHOW_DO_NOT_ASK_AGAIN_CHECKBOX = "KEY_SHOULD_SHOW_DO_NOT_ASK_AGAIN_CHECKBOX"
+private const val KEY_SHOULD_PRESELECT_DO_NOT_ASK_AGAIN_CHECKBOX = "KEY_SHOULD_PRESELECT_DO_NOT_ASK_AGAIN_CHECKBOX"
+private const val KEY_IS_NOTIFICATION_REQUEST = "KEY_IS_NOTIFICATION_REQUEST"
+private const val DEFAULT_VALUE = Int.MAX_VALUE
+private const val KEY_PERMISSION_ID = "KEY_PERMISSION_ID"
+
+internal open class SitePermissionsDialogFragment : AppCompatDialogFragment() {
+
+ // Safe Arguments
+
+ private val safeArguments get() = requireNotNull(arguments)
+
+ internal val sessionId: String get() =
+ safeArguments.getString(KEY_SESSION_ID, "")
+ internal val title: String get() =
+ safeArguments.getString(KEY_TITLE, "")
+ internal val icon get() =
+ safeArguments.getInt(KEY_TITLE_ICON, DEFAULT_VALUE)
+ internal val message: String? get() =
+ safeArguments.getString(KEY_MESSAGE, null)
+ internal val negativeButtonText: String? get() =
+ safeArguments.getString(KEY_NEGATIVE_BUTTON_TEXT, null)
+
+ internal val dialogGravity: Int get() =
+ safeArguments.getInt(KEY_DIALOG_GRAVITY, DEFAULT_VALUE)
+ internal val dialogShouldWidthMatchParent: Boolean get() =
+ safeArguments.getBoolean(KEY_DIALOG_WIDTH_MATCH_PARENT)
+
+ internal val positiveButtonBackgroundColor get() =
+ safeArguments.getInt(KEY_POSITIVE_BUTTON_BACKGROUND_COLOR, DEFAULT_VALUE)
+ internal val positiveButtonTextColor get() =
+ safeArguments.getInt(KEY_POSITIVE_BUTTON_TEXT_COLOR, DEFAULT_VALUE)
+
+ internal val isNotificationRequest get() =
+ safeArguments.getBoolean(KEY_IS_NOTIFICATION_REQUEST, false)
+
+ internal val shouldShowLearnMoreLink: Boolean get() =
+ safeArguments.getBoolean(KEY_SHOULD_SHOW_LEARN_MORE_LINK, false)
+ internal val shouldShowDoNotAskAgainCheckBox: Boolean get() =
+ safeArguments.getBoolean(KEY_SHOULD_SHOW_DO_NOT_ASK_AGAIN_CHECKBOX, true)
+ internal val shouldPreselectDoNotAskAgainCheckBox: Boolean get() =
+ safeArguments.getBoolean(KEY_SHOULD_PRESELECT_DO_NOT_ASK_AGAIN_CHECKBOX, false)
+ internal val permissionRequestId: String get() =
+ safeArguments.getString(KEY_PERMISSION_ID, "")
+
+ // State
+
+ internal var feature: SitePermissionsFeature? = null
+ internal var userSelectionCheckBox: Boolean = false
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ userSelectionCheckBox = shouldPreselectDoNotAskAgainCheckBox
+
+ val sheetDialog = Dialog(requireContext())
+ sheetDialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
+ sheetDialog.setCanceledOnTouchOutside(true)
+
+ val rootView = createContainer()
+
+ sheetDialog.setContainerView(rootView)
+
+ sheetDialog.window?.apply {
+ if (dialogGravity != DEFAULT_VALUE) {
+ setGravity(dialogGravity)
+ }
+
+ if (dialogShouldWidthMatchParent) {
+ setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ // This must be called after addContentView, or it won't fully fill to the edge.
+ setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ }
+ }
+
+ return sheetDialog
+ }
+
+ override fun onDismiss(dialog: DialogInterface) {
+ super.onDismiss(dialog)
+ feature?.onDismiss(permissionRequestId, sessionId)
+ }
+
+ private fun Dialog.setContainerView(rootView: View) {
+ if (dialogShouldWidthMatchParent) {
+ setContentView(rootView)
+ } else {
+ addContentView(
+ rootView,
+ LayoutParams(
+ LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT,
+ ),
+ )
+ }
+ }
+
+ @SuppressLint("InflateParams")
+ private fun createContainer(): View {
+ val rootView = LayoutInflater.from(requireContext()).inflate(
+ R.layout.mozac_site_permissions_prompt,
+ null,
+ false,
+ )
+
+ rootView.findViewById<TextView>(R.id.title).text = title
+ rootView.findViewById<ImageView>(R.id.icon).setImageResource(icon)
+ message?.let {
+ rootView.findViewById<TextView>(R.id.message).apply {
+ visibility = VISIBLE
+ text = it
+ }
+ }
+ if (shouldShowLearnMoreLink) {
+ rootView.findViewById<TextView>(R.id.learn_more).apply {
+ visibility = VISIBLE
+ isLongClickable = false
+ setOnClickListener {
+ dismiss()
+ feature?.onLearnMorePress(permissionRequestId, sessionId)
+ }
+ }
+ }
+
+ val positiveButton = rootView.findViewById<Button>(R.id.allow_button)
+ val negativeButton = rootView.findViewById<Button>(R.id.deny_button)
+
+ positiveButton.setOnClickListener {
+ feature?.onPositiveButtonPress(permissionRequestId, sessionId, userSelectionCheckBox)
+ dismiss()
+ }
+
+ if (positiveButtonBackgroundColor != DEFAULT_VALUE) {
+ val backgroundTintList = ContextCompat.getColorStateList(requireContext(), positiveButtonBackgroundColor)
+ positiveButton.backgroundTintList = backgroundTintList
+ }
+
+ if (positiveButtonTextColor != DEFAULT_VALUE) {
+ val color = ContextCompat.getColor(requireContext(), positiveButtonTextColor)
+ positiveButton.setTextColor(color)
+ }
+
+ negativeButton.setOnClickListener {
+ feature?.onNegativeButtonPress(permissionRequestId, sessionId, userSelectionCheckBox)
+ dismiss()
+ }
+ if (isNotificationRequest) {
+ positiveButton.setText(R.string.mozac_feature_sitepermissions_always_allow)
+ negativeButton.setText(R.string.mozac_feature_sitepermissions_never_allow)
+ }
+ negativeButtonText?.let {
+ negativeButton.text = it
+ }
+
+ if (shouldShowDoNotAskAgainCheckBox) {
+ showDoNotAskAgainCheckbox(rootView, checked = shouldPreselectDoNotAskAgainCheckBox)
+ }
+
+ return rootView
+ }
+
+ private fun showDoNotAskAgainCheckbox(containerView: View, checked: Boolean) {
+ containerView.findViewById<CheckBox>(R.id.do_not_ask_again).apply {
+ visibility = VISIBLE
+ isChecked = checked
+ setOnCheckedChangeListener { _, isChecked ->
+ userSelectionCheckBox = isChecked
+ }
+ }
+ }
+
+ companion object {
+ fun newInstance(
+ sessionId: String,
+ title: String,
+ titleIcon: Int,
+ permissionRequestId: String = "",
+ feature: SitePermissionsFeature,
+ shouldShowDoNotAskAgainCheckBox: Boolean,
+ shouldSelectDoNotAskAgainCheckBox: Boolean = false,
+ isNotificationRequest: Boolean = false,
+ message: String? = null,
+ negativeButtonText: String? = null,
+ shouldShowLearnMoreLink: Boolean = false,
+ ): SitePermissionsDialogFragment {
+ val fragment = SitePermissionsDialogFragment()
+ val arguments = fragment.arguments ?: Bundle()
+
+ arguments.apply {
+ putString(KEY_SESSION_ID, sessionId)
+ putString(KEY_TITLE, title)
+ putInt(KEY_TITLE_ICON, titleIcon)
+ putString(KEY_MESSAGE, message)
+ putString(KEY_NEGATIVE_BUTTON_TEXT, negativeButtonText)
+ putString(KEY_PERMISSION_ID, permissionRequestId)
+ putBoolean(KEY_SHOULD_SHOW_LEARN_MORE_LINK, shouldShowLearnMoreLink)
+
+ putBoolean(KEY_IS_NOTIFICATION_REQUEST, isNotificationRequest)
+ if (isNotificationRequest) {
+ putBoolean(KEY_SHOULD_SHOW_DO_NOT_ASK_AGAIN_CHECKBOX, false)
+ putBoolean(KEY_SHOULD_PRESELECT_DO_NOT_ASK_AGAIN_CHECKBOX, true)
+ } else {
+ putBoolean(KEY_SHOULD_SHOW_DO_NOT_ASK_AGAIN_CHECKBOX, shouldShowDoNotAskAgainCheckBox)
+ putBoolean(KEY_SHOULD_PRESELECT_DO_NOT_ASK_AGAIN_CHECKBOX, shouldSelectDoNotAskAgainCheckBox)
+ }
+
+ feature.promptsStyling?.apply {
+ putInt(KEY_DIALOG_GRAVITY, gravity)
+ putBoolean(KEY_DIALOG_WIDTH_MATCH_PARENT, shouldWidthMatchParent)
+
+ positiveButtonBackgroundColor?.apply {
+ putInt(KEY_POSITIVE_BUTTON_BACKGROUND_COLOR, this)
+ }
+
+ positiveButtonTextColor?.apply {
+ putInt(KEY_POSITIVE_BUTTON_TEXT_COLOR, this)
+ }
+ }
+ }
+ fragment.feature = feature
+ fragment.arguments = arguments
+ return fragment
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFacts.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFacts.kt
new file mode 100644
index 0000000000..580df84f79
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFacts.kt
@@ -0,0 +1,65 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import mozilla.components.concept.engine.permission.Permission
+import mozilla.components.support.base.Component.FEATURE_SITEPERMISSIONS
+import mozilla.components.support.base.facts.Action
+import mozilla.components.support.base.facts.Fact
+import mozilla.components.support.base.facts.collect
+
+/**
+ * Facts emitted for telemetry related to the site permissions prompt.
+ */
+class SitePermissionsFacts {
+ /**
+ * Specific types of telemetry items.
+ */
+ object Items {
+ const val PERMISSIONS = "permissions"
+ }
+}
+
+internal fun emitPermissionDialogDisplayed(permission: Permission) = emitSitePermissionsFact(
+ action = Action.DISPLAY,
+ permissions = permission.name,
+)
+
+internal fun emitPermissionsDialogDisplayed(permissions: List<Permission>) = emitSitePermissionsFact(
+ action = Action.DISPLAY,
+ permissions = permissions.distinctBy { it.name }.joinToString { it.name },
+)
+
+internal fun emitPermissionDenied(permission: Permission) = emitSitePermissionsFact(
+ action = Action.CANCEL,
+ permissions = permission.name,
+)
+
+internal fun emitPermissionsDenied(permissions: List<Permission>) = emitSitePermissionsFact(
+ action = Action.CANCEL,
+ permissions = permissions.distinctBy { it.name }.joinToString { it.name },
+)
+
+internal fun emitPermissionAllowed(permission: Permission) = emitSitePermissionsFact(
+ action = Action.CONFIRM,
+ permissions = permission.name,
+)
+
+internal fun emitPermissionsAllowed(permissions: List<Permission>) = emitSitePermissionsFact(
+ action = Action.CONFIRM,
+ permissions = permissions.distinctBy { it.name }.joinToString { it.name },
+)
+
+private fun emitSitePermissionsFact(
+ action: Action,
+ permissions: String,
+) {
+ Fact(
+ FEATURE_SITEPERMISSIONS,
+ action,
+ SitePermissionsFacts.Items.PERMISSIONS,
+ permissions,
+ ).collect()
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
new file mode 100644
index 0000000000..cea90ffe2d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsFeature.kt
@@ -0,0 +1,1057 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import android.Manifest.permission.CAMERA
+import android.Manifest.permission.RECORD_AUDIO
+import android.content.Context
+import android.content.pm.PackageManager
+import androidx.annotation.ColorRes
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.annotation.VisibleForTesting
+import androidx.fragment.app.FragmentManager
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.distinctUntilChangedBy
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import mozilla.components.browser.state.action.ContentAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayAudibleBlockingAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayAudibleChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayInAudibleBlockingAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayInAudibleChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.CameraChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.LocationChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.MediaKeySystemAccesChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.MicrophoneChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.NotificationChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.PersistentStorageChangedAction
+import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab
+import mozilla.components.browser.state.state.ContentState
+import mozilla.components.browser.state.state.SessionState
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.permission.Permission
+import mozilla.components.concept.engine.permission.Permission.AppAudio
+import mozilla.components.concept.engine.permission.Permission.AppCamera
+import mozilla.components.concept.engine.permission.Permission.AppLocationCoarse
+import mozilla.components.concept.engine.permission.Permission.AppLocationFine
+import mozilla.components.concept.engine.permission.Permission.ContentAudioCapture
+import mozilla.components.concept.engine.permission.Permission.ContentAudioMicrophone
+import mozilla.components.concept.engine.permission.Permission.ContentAutoPlayAudible
+import mozilla.components.concept.engine.permission.Permission.ContentAutoPlayInaudible
+import mozilla.components.concept.engine.permission.Permission.ContentCrossOriginStorageAccess
+import mozilla.components.concept.engine.permission.Permission.ContentGeoLocation
+import mozilla.components.concept.engine.permission.Permission.ContentMediaKeySystemAccess
+import mozilla.components.concept.engine.permission.Permission.ContentNotification
+import mozilla.components.concept.engine.permission.Permission.ContentPersistentStorage
+import mozilla.components.concept.engine.permission.Permission.ContentVideoCamera
+import mozilla.components.concept.engine.permission.Permission.ContentVideoCapture
+import mozilla.components.concept.engine.permission.PermissionRequest
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.BLOCKED
+import mozilla.components.concept.engine.permission.SitePermissionsStorage
+import mozilla.components.feature.session.SessionUseCases
+import mozilla.components.feature.sitepermissions.SitePermissionsFeature.DialogConfig
+import mozilla.components.feature.tabs.TabsUseCases.SelectOrAddUseCase
+import mozilla.components.lib.state.ext.flowScoped
+import mozilla.components.support.base.feature.LifecycleAwareFeature
+import mozilla.components.support.base.feature.OnNeedToRequestPermissions
+import mozilla.components.support.base.feature.PermissionsFeature
+import mozilla.components.support.base.log.logger.Logger
+import mozilla.components.support.ktx.android.content.isPermissionGranted
+import mozilla.components.support.ktx.kotlin.getOrigin
+import mozilla.components.support.ktx.kotlin.stripDefaultPort
+import mozilla.components.support.ktx.kotlinx.coroutines.flow.filterChanged
+import java.security.InvalidParameterException
+import mozilla.components.ui.icons.R as iconsR
+
+internal const val PROMPT_FRAGMENT_TAG = "mozac_feature_sitepermissions_prompt_dialog"
+
+@VisibleForTesting
+internal const val STORAGE_ACCESS_DOCUMENTATION_URL =
+ "https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API"
+
+/**
+ * This feature will collect [PermissionRequest] from [ContentState] and display
+ * suitable [SitePermissionsDialogFragment].
+ * Once the dialog is closed the [PermissionRequest] will be consumed.
+ *
+ * @property context a reference to the context.
+ * @property sessionId optional sessionId to be observed if null the selected session will be observed.
+ * @property storage the object in charge of persisting all the [SitePermissions] objects.
+ * @property sitePermissionsRules indicates how permissions should behave per permission category.
+ * @property fragmentManager a reference to a [FragmentManager], used to show permissions prompts.
+ * @property promptsStyling optional styling for prompts.
+ * @property dialogConfig optional customization for dialog initial state. See [DialogConfig].
+ * @property onNeedToRequestPermissions a callback invoked when permissions
+ * need to be requested. Once the request is completed, [onPermissionsResult] needs to be invoked.
+ * @property onShouldShowRequestPermissionRationale a callback that allows the feature to query
+ * the ActivityCompat.shouldShowRequestPermissionRationale or the Fragment.shouldShowRequestPermissionRationale values.
+ * @property exitFullscreenUseCase optional the use case in charge of exiting fullscreen
+ * @property shouldShowDoNotAskAgainCheckBox optional Visibility for Do not ask again Checkbox
+ **/
+
+@Suppress("TooManyFunctions", "LargeClass")
+class SitePermissionsFeature(
+ private val context: Context,
+ @set:VisibleForTesting
+ internal var sessionId: String? = null,
+ private val storage: SitePermissionsStorage = OnDiskSitePermissionsStorage(context),
+ var sitePermissionsRules: SitePermissionsRules? = null,
+ private val fragmentManager: FragmentManager,
+ var promptsStyling: PromptsStyling? = null,
+ private val dialogConfig: DialogConfig? = null,
+ override val onNeedToRequestPermissions: OnNeedToRequestPermissions,
+ val onShouldShowRequestPermissionRationale: (permission: String) -> Boolean,
+ private val store: BrowserStore,
+ private val exitFullscreenUseCase: SessionUseCases.ExitFullScreenUseCase = SessionUseCases(store).exitFullscreen,
+ private val shouldShowDoNotAskAgainCheckBox: Boolean = true,
+) : LifecycleAwareFeature, PermissionsFeature {
+ @VisibleForTesting
+ internal val selectOrAddUseCase by lazy {
+ SelectOrAddUseCase(store)
+ }
+
+ private val logger = Logger("SitePermissionsFeature")
+
+ internal val ioCoroutineScope by lazy { coroutineScopeInitializer() }
+
+ internal var coroutineScopeInitializer = {
+ CoroutineScope(Dispatchers.IO)
+ }
+ private var sitePermissionScope: CoroutineScope? = null
+ private var appPermissionScope: CoroutineScope? = null
+ private var loadingScope: CoroutineScope? = null
+
+ override fun start() {
+ fragmentManager.findFragmentByTag(PROMPT_FRAGMENT_TAG)?.let { fragment ->
+ // There's still a [SitePermissionsDialogFragment] visible from the last time. Re-attach
+ // this feature so that the fragment can invoke the callback on this feature once the user
+ // makes a selection. This can happen when the app was in the background and on resume
+ // the activity and fragments get recreated.
+ reattachFragment(fragment as SitePermissionsDialogFragment)
+ }
+
+ setupPermissionRequestsCollector()
+ setupAppPermissionRequestsCollector()
+ setupLoadingCollector()
+ }
+
+ @VisibleForTesting
+ internal fun setupLoadingCollector() {
+ loadingScope = store.flowScoped { flow ->
+ flow.mapNotNull { state ->
+ state.findTabOrCustomTabOrSelectedTab(sessionId)
+ }.distinctUntilChangedBy { it.content.loading }.collect { tab ->
+ if (tab.content.loading) {
+ // Clears stale permission indicators in the toolbar,
+ // after the session starts loading.
+ store.dispatch(UpdatePermissionHighlightsStateAction.Reset(tab.id))
+ storage.clearTemporaryPermissions()
+ }
+ }
+ }
+ }
+
+ @VisibleForTesting
+ internal fun setupAppPermissionRequestsCollector() {
+ appPermissionScope =
+ store.flowScoped { flow ->
+ flow.mapNotNull { state ->
+ state.findTabOrCustomTabOrSelectedTab(sessionId)?.content?.appPermissionRequestsList
+ }
+ .filterChanged { it }
+ .collect { appPermissionRequest ->
+ val permissions = appPermissionRequest.permissions.map { it.id ?: "" }
+ onNeedToRequestPermissions(permissions.toTypedArray())
+ }
+ }
+ }
+
+ @VisibleForTesting
+ internal fun setupPermissionRequestsCollector() {
+ sitePermissionScope =
+ store.flowScoped { flow ->
+ flow.mapNotNull { state ->
+ state.findTabOrCustomTabOrSelectedTab(sessionId)?.content?.permissionRequestsList
+ }
+ .filterChanged { it }
+ .collect { permissionRequest ->
+ val origin: String = permissionRequest.uri?.getOrigin().orEmpty()
+
+ if (origin.isEmpty()) {
+ permissionRequest.consumeAndReject()
+ } else {
+ if (permissionRequest.permissions.all { it.isSupported() }) {
+ onContentPermissionRequested(
+ permissionRequest,
+ origin,
+ )
+ } else {
+ permissionRequest.consumeAndReject()
+ }
+ }
+ }
+ }
+ }
+
+ private fun PermissionRequest.consumeAndReject() {
+ consumePermissionRequest(this)
+ this.reject()
+ }
+
+ @VisibleForTesting
+ internal fun consumePermissionRequest(
+ permissionRequest: PermissionRequest,
+ optionalSessionId: String? = null,
+ ) {
+ val thisSessionId = optionalSessionId ?: getCurrentTabState()?.id
+ thisSessionId?.let { sessionId ->
+ store.dispatch(ContentAction.ConsumePermissionsRequest(sessionId, permissionRequest))
+ }
+ }
+
+ @VisibleForTesting
+ internal fun consumeAppPermissionRequest(
+ appPermissionRequest: PermissionRequest,
+ optionalSessionId: String? = null,
+ ) {
+ val thisSessionId = optionalSessionId ?: getCurrentTabState()?.id
+ thisSessionId?.let { sessionId ->
+ store.dispatch(
+ ContentAction.ConsumeAppPermissionsRequest(
+ sessionId,
+ appPermissionRequest,
+ ),
+ )
+ }
+ }
+
+ override fun stop() {
+ sitePermissionScope?.cancel()
+ appPermissionScope?.cancel()
+ loadingScope?.cancel()
+ storage.clearTemporaryPermissions()
+ }
+
+ /**
+ * Notifies the feature that the permissions requested were completed.
+ *
+ * @param grantResults the grant results for the corresponding permissions
+ * @see [onNeedToRequestPermissions].
+ */
+ @Suppress("NestedBlockDepth")
+ override fun onPermissionsResult(permissions: Array<String>, grantResults: IntArray) {
+ val currentContentSate = getCurrentContentState()
+ val appPermissionRequest = findRequestedAppPermission(permissions)
+
+ if (appPermissionRequest != null && currentContentSate != null) {
+ val allPermissionWereGranted = grantResults.all { grantResult ->
+ grantResult == PackageManager.PERMISSION_GRANTED
+ }
+
+ if (grantResults.isNotEmpty() && allPermissionWereGranted) {
+ appPermissionRequest.grant()
+ } else {
+ appPermissionRequest.reject()
+ permissions.forEach { systemPermission ->
+ if (!onShouldShowRequestPermissionRationale(systemPermission)) {
+ // The system permission is denied permanently
+ storeSitePermissions(
+ currentContentSate,
+ appPermissionRequest,
+ status = BLOCKED,
+ )
+ }
+ }
+ }
+ consumeAppPermissionRequest(appPermissionRequest)
+ }
+ }
+
+ @VisibleForTesting
+ internal fun getCurrentContentState() = getCurrentTabState()?.content
+
+ @VisibleForTesting
+ internal fun getCurrentTabState() = store.state.findTabOrCustomTabOrSelectedTab(sessionId)
+
+ @VisibleForTesting
+ internal fun findRequestedAppPermission(permissions: Array<String>): PermissionRequest? {
+ return getCurrentContentState()?.appPermissionRequestsList?.find {
+ permissions.contains(it.permissions.first().id)
+ }
+ }
+
+ @VisibleForTesting
+ internal fun findRequestedPermission(permissionId: String): PermissionRequest? {
+ return getCurrentContentState()?.permissionRequestsList?.find {
+ it.id == permissionId
+ }
+ }
+
+ @VisibleForTesting
+ internal fun onContentPermissionGranted(
+ permissionRequest: PermissionRequest,
+ shouldStore: Boolean,
+ ) {
+ permissionRequest.grant()
+ if (shouldStore) {
+ getCurrentContentState()?.let { contentState ->
+ storeSitePermissions(contentState, permissionRequest, ALLOWED)
+ }
+ } else {
+ storage.saveTemporary(permissionRequest)
+ }
+ }
+
+ internal fun onPositiveButtonPress(
+ permissionId: String,
+ sessionId: String,
+ shouldStore: Boolean,
+ ) {
+ findRequestedPermission(permissionId)?.let { permissionRequest ->
+ consumePermissionRequest(permissionRequest, sessionId)
+ onContentPermissionGranted(permissionRequest, shouldStore)
+
+ if (!permissionRequest.containsVideoAndAudioSources()) {
+ emitPermissionAllowed(permissionRequest.permissions.first())
+ } else {
+ emitPermissionsAllowed(permissionRequest.permissions)
+ }
+ }
+ }
+
+ internal fun onNegativeButtonPress(
+ permissionId: String,
+ sessionId: String,
+ shouldStore: Boolean,
+ ) {
+ findRequestedPermission(permissionId)?.let { permissionRequest ->
+ consumePermissionRequest(permissionRequest, sessionId)
+ onContentPermissionDeny(permissionRequest, shouldStore)
+
+ if (!permissionRequest.containsVideoAndAudioSources()) {
+ emitPermissionDenied(permissionRequest.permissions.first())
+ } else {
+ emitPermissionsDenied(permissionRequest.permissions)
+ }
+ }
+ }
+
+ internal fun onLearnMorePress(
+ permissionId: String,
+ sessionId: String,
+ ) {
+ findRequestedPermission(permissionId)?.let { permissionRequest ->
+ consumePermissionRequest(permissionRequest, sessionId)
+ onContentPermissionDeny(permissionRequest, false)
+
+ val permission = permissionRequest.permissions.first()
+ if (permission is ContentCrossOriginStorageAccess) {
+ store.state.findTabOrCustomTabOrSelectedTab(sessionId)?.let {
+ selectOrAddUseCase.invoke(
+ url = STORAGE_ACCESS_DOCUMENTATION_URL,
+ private = it.content.private,
+ source = SessionState.Source.Internal.TextSelection,
+ )
+ }
+ }
+ }
+ }
+
+ internal fun onDismiss(
+ permissionId: String,
+ sessionId: String,
+ ) {
+ findRequestedPermission(permissionId)?.let { permissionRequest ->
+ consumePermissionRequest(permissionRequest, sessionId)
+ onContentPermissionDeny(permissionRequest, false)
+ }
+ }
+
+ internal fun storeSitePermissions(
+ contentState: ContentState,
+ request: PermissionRequest,
+ status: SitePermissions.Status,
+ coroutineScope: CoroutineScope = ioCoroutineScope,
+ ) {
+ if (contentState.private) {
+ return
+ }
+ updatePermissionToolbarIndicator(request, status, true)
+ coroutineScope.launch {
+ request.uri?.getOrigin()?.let { origin ->
+ var sitePermissions =
+ storage.findSitePermissionsBy(origin, private = false)
+
+ if (sitePermissions == null) {
+ sitePermissions =
+ request.toSitePermissions(
+ origin,
+ status = status,
+ permissions = request.permissions,
+ )
+ storage.save(sitePermissions, request, private = false)
+ } else {
+ sitePermissions = request.toSitePermissions(origin, status, sitePermissions)
+ storage.update(sitePermissions = sitePermissions, private = false)
+ }
+ }
+ }
+ }
+
+ internal fun onContentPermissionDeny(
+ permissionRequest: PermissionRequest,
+ shouldStore: Boolean,
+ ) {
+ permissionRequest.reject()
+ if (shouldStore) {
+ getCurrentContentState()?.let { contentState ->
+ storeSitePermissions(contentState, permissionRequest, BLOCKED)
+ }
+ } else {
+ storage.saveTemporary(permissionRequest)
+ }
+ }
+
+ internal suspend fun onContentPermissionRequested(
+ permissionRequest: PermissionRequest,
+ origin: String,
+ coroutineScope: CoroutineScope = ioCoroutineScope,
+ ): SitePermissionsDialogFragment? {
+ // We want to warranty that all media permissions have the required system
+ // permissions are granted first, otherwise, we reject the request
+ if (permissionRequest.isMedia && !permissionRequest.areAllMediaPermissionsGranted) {
+ permissionRequest.reject()
+ consumePermissionRequest(permissionRequest)
+ return null
+ }
+ val tab = store.state.findTabOrCustomTabOrSelectedTab(sessionId)
+ if (tab == null) {
+ logger.error("Unable to find a tab for $sessionId rejecting the prompt request")
+ permissionRequest.reject()
+ consumePermissionRequest(permissionRequest)
+ return null
+ }
+
+ val permissionFromStorage = withContext(coroutineScope.coroutineContext) {
+ storage.findSitePermissionsBy(origin, private = tab.content.private)
+ }
+ val prompt = if (shouldApplyRules(permissionFromStorage)) {
+ handleRuledFlow(permissionRequest, origin)
+ } else {
+ handleNoRuledFlow(permissionFromStorage, permissionRequest, origin)
+ }
+
+ return if (prompt == null) {
+ null
+ } else {
+ // If we are in fullscreen, then exit to show the permission prompt.
+ // This won't have any effect if we are not in fullscreen.
+ exitFullscreenUseCase.invoke(tab.id)
+ prompt.show(fragmentManager, PROMPT_FRAGMENT_TAG)
+ prompt
+ }
+ }
+
+ @VisibleForTesting
+ internal fun handleNoRuledFlow(
+ permissionFromStorage: SitePermissions?,
+ permissionRequest: PermissionRequest,
+ host: String,
+ ): SitePermissionsDialogFragment? {
+ return if (shouldShowPrompt(permissionRequest, permissionFromStorage)) {
+ createPrompt(permissionRequest, host)
+ } else {
+ val status = if (permissionFromStorage.isGranted(permissionRequest)) {
+ permissionRequest.grant()
+ ALLOWED
+ } else {
+ permissionRequest.reject()
+ BLOCKED
+ }
+ updatePermissionToolbarIndicator(
+ permissionRequest,
+ status,
+ permissionFromStorage != null,
+ )
+ consumePermissionRequest(permissionRequest)
+ null
+ }
+ }
+
+ @VisibleForTesting
+ internal fun shouldShowPrompt(
+ permissionRequest: PermissionRequest,
+ permissionFromStorage: SitePermissions?,
+ ): Boolean {
+ return if (permissionRequest.isForAutoplay()) {
+ false
+ } else {
+ (
+ permissionFromStorage == null ||
+ !permissionRequest.doNotAskAgain(permissionFromStorage)
+ )
+ }
+ }
+
+ @VisibleForTesting
+ internal fun handleRuledFlow(
+ permissionRequest: PermissionRequest,
+ origin: String,
+ ): SitePermissionsDialogFragment? {
+ return when (sitePermissionsRules?.getActionFrom(permissionRequest)) {
+ SitePermissionsRules.Action.ALLOWED -> {
+ permissionRequest.grant()
+ consumePermissionRequest(permissionRequest)
+ updatePermissionToolbarIndicator(permissionRequest, ALLOWED)
+ null
+ }
+ SitePermissionsRules.Action.BLOCKED -> {
+ permissionRequest.reject()
+ consumePermissionRequest(permissionRequest)
+ updatePermissionToolbarIndicator(permissionRequest, BLOCKED)
+ null
+ }
+ SitePermissionsRules.Action.ASK_TO_ALLOW -> {
+ createPrompt(permissionRequest, origin)
+ }
+ null -> {
+ consumePermissionRequest(permissionRequest)
+ null
+ }
+ }
+ }
+
+ @VisibleForTesting
+ @Suppress("ComplexMethod")
+ internal fun updatePermissionToolbarIndicator(
+ request: PermissionRequest,
+ value: SitePermissions.Status,
+ permanent: Boolean = false,
+ ) {
+ val isAutoPlayAudibleBlocking: Boolean? =
+ if (request.isForAutoplayAudible()) value == BLOCKED else null
+ val isAutoPlayInAudibleBlocking: Boolean? =
+ if (request.isForAutoplayInaudible()) value == BLOCKED else null
+
+ getCurrentTabState()?.let { tab ->
+ // At the moment, we don't have APIs for controlling temporary permissions,
+ // after they are ALLOWED/BLOCKED, for this reason, we are not notifying users
+ // when permissions have changed from their default values,
+ // as they are not going have a way to change permissions.
+ // Either way, temporary permissions have to be ALLOWED/BLOCKED per sessions
+ // users are already aware of them.
+ // The autoplay permissions work a bit different, as it is a global permissions,
+ // users are never prompt to select its value, and it can't be temporary,
+ // they only can change it's value per site persistently.
+ if (permanent || request.isForAutoplay()) {
+ val action = when {
+ request.isForNotification() -> NotificationChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.notification?.toStatus(),
+ )
+ request.isForCamera() -> CameraChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.camera?.toStatus(),
+ )
+ request.isForLocation() -> LocationChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.location?.toStatus(),
+ )
+ request.isForMicrophone() -> MicrophoneChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.microphone?.toStatus(),
+ )
+ request.isForPersistentStorage() -> PersistentStorageChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.persistentStorage?.toStatus(),
+ )
+ request.isForMediaKeySystemAccess() -> MediaKeySystemAccesChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.mediaKeySystemAccess?.toStatus(),
+ )
+ request.isForAutoplayAudible() -> AutoPlayAudibleChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.autoplayAudible?.toAutoplayStatus()
+ ?.toStatus(),
+ )
+ request.isForAutoplayInaudible() -> AutoPlayInAudibleChangedAction(
+ tab.id,
+ value != sitePermissionsRules?.autoplayInaudible?.toAutoplayStatus()
+ ?.toStatus(),
+ )
+ else -> null
+ }
+ action?.let {
+ store.dispatch(it)
+ }
+ }
+ isAutoPlayAudibleBlocking?.let {
+ store.dispatch(AutoPlayAudibleBlockingAction(tab.id, it))
+ }
+ isAutoPlayInAudibleBlocking?.let {
+ store.dispatch(AutoPlayInAudibleBlockingAction(tab.id, it))
+ }
+ }
+ }
+
+ @VisibleForTesting
+ internal fun shouldApplyRules(permissionFromStorage: SitePermissions?) =
+ sitePermissionsRules != null && permissionFromStorage == null
+
+ private fun PermissionRequest.doNotAskAgain(permissionFromStore: SitePermissions): Boolean {
+ return permissions.any { permission ->
+ when (permission) {
+ is ContentGeoLocation -> {
+ permissionFromStore.location.doNotAskAgain()
+ }
+ is ContentNotification -> {
+ permissionFromStore.notification.doNotAskAgain()
+ }
+ is ContentAudioCapture, is ContentAudioMicrophone -> {
+ permissionFromStore.microphone.doNotAskAgain()
+ }
+ is ContentVideoCamera, is ContentVideoCapture -> {
+ permissionFromStore.camera.doNotAskAgain()
+ }
+ is ContentPersistentStorage -> {
+ permissionFromStore.localStorage.doNotAskAgain()
+ }
+ is ContentMediaKeySystemAccess -> {
+ permissionFromStore.mediaKeySystemAccess.doNotAskAgain()
+ }
+ is ContentCrossOriginStorageAccess -> {
+ permissionFromStore.crossOriginStorageAccess.doNotAskAgain()
+ }
+ else -> false
+ }
+ }
+ }
+
+ private fun PermissionRequest.toSitePermissions(
+ host: String,
+ status: SitePermissions.Status,
+ initialSitePermission: SitePermissions = getInitialSitePermissions(host),
+ permissions: List<Permission> = this.permissions,
+ ): SitePermissions {
+ var sitePermissions = initialSitePermission
+ for (permission in permissions) {
+ sitePermissions = updateSitePermissionsStatus(status, permission, sitePermissions)
+ }
+ return sitePermissions
+ }
+
+ @VisibleForTesting
+ internal fun getInitialSitePermissions(
+ host: String,
+ ): SitePermissions {
+ val rules = sitePermissionsRules
+ return rules?.toSitePermissions(
+ host,
+ savedAt = System.currentTimeMillis(),
+ )
+ ?: SitePermissions(host, savedAt = System.currentTimeMillis())
+ }
+
+ private fun PermissionRequest.isForAutoplay() =
+ this.permissions.any { it is ContentAutoPlayInaudible || it is ContentAutoPlayAudible }
+
+ private fun PermissionRequest.isForNotification() =
+ this.permissions.any { it is ContentNotification }
+
+ private fun PermissionRequest.isForCamera() =
+ this.permissions.any {
+ it is ContentVideoCamera || it is ContentVideoCapture || it is AppCamera
+ }
+
+ private fun PermissionRequest.isForAutoplayInaudible() =
+ this.permissions.any { it is ContentAutoPlayInaudible }
+
+ private fun PermissionRequest.isForAutoplayAudible() =
+ this.permissions.any { it is ContentAutoPlayAudible }
+
+ private fun PermissionRequest.isForLocation() =
+ this.permissions.any {
+ it is ContentGeoLocation ||
+ it is AppLocationCoarse ||
+ it is AppLocationFine
+ }
+
+ private fun PermissionRequest.isForMicrophone() =
+ this.permissions.any {
+ it is ContentAudioCapture || it is ContentAudioMicrophone ||
+ it is AppAudio
+ }
+
+ private fun PermissionRequest.isForPersistentStorage() =
+ this.permissions.any { it is ContentPersistentStorage }
+
+ private fun PermissionRequest.isForMediaKeySystemAccess() =
+ this.permissions.any { it is ContentMediaKeySystemAccess }
+
+ @VisibleForTesting
+ internal fun updateSitePermissionsStatus(
+ status: SitePermissions.Status,
+ permission: Permission,
+ sitePermissions: SitePermissions,
+ ): SitePermissions {
+ return when (permission) {
+ is ContentGeoLocation, is AppLocationCoarse, is AppLocationFine -> {
+ sitePermissions.copy(location = status)
+ }
+ is ContentNotification -> {
+ sitePermissions.copy(notification = status)
+ }
+ is ContentAudioCapture, is ContentAudioMicrophone, is AppAudio -> {
+ sitePermissions.copy(microphone = status)
+ }
+ is ContentVideoCamera, is ContentVideoCapture, is AppCamera -> {
+ sitePermissions.copy(camera = status)
+ }
+ is ContentAutoPlayAudible -> {
+ sitePermissions.copy(autoplayAudible = status.toAutoplayStatus())
+ }
+ is ContentAutoPlayInaudible -> {
+ sitePermissions.copy(autoplayInaudible = status.toAutoplayStatus())
+ }
+ is ContentPersistentStorage -> {
+ sitePermissions.copy(localStorage = status)
+ }
+ is ContentMediaKeySystemAccess -> {
+ sitePermissions.copy(mediaKeySystemAccess = status)
+ }
+ is ContentCrossOriginStorageAccess -> {
+ sitePermissions.copy(crossOriginStorageAccess = status)
+ }
+ else ->
+ throw InvalidParameterException("$permission is not a valid permission.")
+ }
+ }
+
+ @VisibleForTesting
+ internal fun createPrompt(
+ permissionRequest: PermissionRequest,
+ host: String,
+ ): SitePermissionsDialogFragment {
+ return if (!permissionRequest.containsVideoAndAudioSources()) {
+ val permission = permissionRequest.permissions.first()
+ handlingSingleContentPermissions(permissionRequest, permission, host).also {
+ emitPermissionDialogDisplayed(permission)
+ }
+ } else {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_camera_and_microphone,
+ iconsR.drawable.mozac_ic_microphone_24,
+ showDoNotAskAgainCheckBox = shouldShowDoNotAskAgainCheckBox,
+ shouldSelectRememberChoice = dialogConfig?.shouldPreselectDoNotAskAgain
+ ?: DialogConfig.DEFAULT_PRESELECT_DO_NOT_ASK_AGAIN,
+ ).also {
+ emitPermissionsDialogDisplayed(permissionRequest.permissions)
+ }
+ }
+ }
+
+ @Suppress("LongMethod")
+ @VisibleForTesting
+ internal fun handlingSingleContentPermissions(
+ permissionRequest: PermissionRequest,
+ permission: Permission,
+ host: String,
+ ): SitePermissionsDialogFragment {
+ return when (permission) {
+ is ContentGeoLocation -> {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_location_title,
+ iconsR.drawable.mozac_ic_location_24,
+ showDoNotAskAgainCheckBox = shouldShowDoNotAskAgainCheckBox,
+ shouldSelectRememberChoice = dialogConfig?.shouldPreselectDoNotAskAgain
+ ?: DialogConfig.DEFAULT_PRESELECT_DO_NOT_ASK_AGAIN,
+ )
+ }
+ is ContentNotification -> {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_notification_title,
+ iconsR.drawable.mozac_ic_notification_24,
+ showDoNotAskAgainCheckBox = false,
+ shouldSelectRememberChoice = false,
+ isNotificationRequest = true,
+ )
+ }
+ is ContentAudioCapture, is ContentAudioMicrophone -> {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_microfone_title,
+ iconsR.drawable.mozac_ic_microphone_24,
+ showDoNotAskAgainCheckBox = shouldShowDoNotAskAgainCheckBox,
+ shouldSelectRememberChoice = dialogConfig?.shouldPreselectDoNotAskAgain
+ ?: DialogConfig.DEFAULT_PRESELECT_DO_NOT_ASK_AGAIN,
+ )
+ }
+ is ContentVideoCamera, is ContentVideoCapture -> {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_camera_title,
+ iconsR.drawable.mozac_ic_camera_24,
+ showDoNotAskAgainCheckBox = shouldShowDoNotAskAgainCheckBox,
+ shouldSelectRememberChoice = dialogConfig?.shouldPreselectDoNotAskAgain
+ ?: DialogConfig.DEFAULT_PRESELECT_DO_NOT_ASK_AGAIN,
+ )
+ }
+ is ContentPersistentStorage -> {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_persistent_storage_title,
+ iconsR.drawable.mozac_ic_storage_24,
+ showDoNotAskAgainCheckBox = false,
+ shouldSelectRememberChoice = true,
+ )
+ }
+ is ContentMediaKeySystemAccess -> {
+ createSinglePermissionPrompt(
+ context,
+ host,
+ permissionRequest,
+ R.string.mozac_feature_sitepermissions_media_key_system_access_title,
+ iconsR.drawable.mozac_ic_link_24,
+ showDoNotAskAgainCheckBox = false,
+ shouldSelectRememberChoice = true,
+ )
+ }
+ is ContentCrossOriginStorageAccess -> {
+ createContentCrossOriginStorageAccessPermissionPrompt(
+ context = context,
+ host = host,
+ permissionRequest = permissionRequest,
+ showDoNotAskAgainCheckBox = false,
+ shouldSelectRememberChoice = true,
+ )
+ }
+ else ->
+ throw InvalidParameterException("$permission is not a valid permission.")
+ }
+ }
+
+ @VisibleForTesting
+ internal fun createSinglePermissionPrompt(
+ context: Context,
+ host: String,
+ permissionRequest: PermissionRequest,
+ @StringRes titleId: Int,
+ @DrawableRes iconId: Int,
+ showDoNotAskAgainCheckBox: Boolean,
+ shouldSelectRememberChoice: Boolean,
+ isNotificationRequest: Boolean = false,
+ ): SitePermissionsDialogFragment {
+ val title = context.getString(titleId, host)
+
+ val currentSessionId: String = store.state.findTabOrCustomTabOrSelectedTab(sessionId)?.id
+ ?: throw IllegalStateException("Unable to find session for $sessionId or selected session")
+
+ return SitePermissionsDialogFragment.newInstance(
+ currentSessionId,
+ title,
+ iconId,
+ permissionRequest.id,
+ this,
+ showDoNotAskAgainCheckBox,
+ isNotificationRequest = isNotificationRequest,
+ shouldSelectDoNotAskAgainCheckBox = shouldSelectRememberChoice,
+ )
+ }
+
+ @VisibleForTesting
+ internal fun createContentCrossOriginStorageAccessPermissionPrompt(
+ context: Context,
+ host: String,
+ permissionRequest: PermissionRequest,
+ showDoNotAskAgainCheckBox: Boolean,
+ shouldSelectRememberChoice: Boolean,
+ ): SitePermissionsDialogFragment {
+ val currentSession = store.state.findTabOrCustomTabOrSelectedTab(sessionId)
+ ?: throw IllegalStateException("Unable to find session for $sessionId or selected session")
+
+ val title = context.getString(
+ R.string.mozac_feature_sitepermissions_storage_access_title,
+ host.stripDefaultPort(),
+ currentSession.content.url.stripDefaultPort(),
+ )
+ val message = context.getString(
+ R.string.mozac_feature_sitepermissions_storage_access_message,
+ host.stripDefaultPort(),
+ )
+ val negativeButtonText = context.getString(R.string.mozac_feature_sitepermissions_storage_access_not_allow)
+
+ return SitePermissionsDialogFragment.newInstance(
+ sessionId = currentSession.id,
+ title = title,
+ titleIcon = iconsR.drawable.mozac_ic_cookies_24,
+ message = message,
+ negativeButtonText = negativeButtonText,
+ permissionRequestId = permissionRequest.id,
+ feature = this,
+ shouldShowDoNotAskAgainCheckBox = showDoNotAskAgainCheckBox,
+ isNotificationRequest = false,
+ shouldSelectDoNotAskAgainCheckBox = shouldSelectRememberChoice,
+ shouldShowLearnMoreLink = true,
+ )
+ }
+
+ private val PermissionRequest.isMedia: Boolean
+ get() {
+ return when (permissions.first()) {
+ is ContentVideoCamera, is ContentVideoCapture,
+ is ContentAudioCapture, is ContentAudioMicrophone,
+ -> true
+ else -> false
+ }
+ }
+
+ private val PermissionRequest.areAllMediaPermissionsGranted: Boolean
+ get() {
+ val systemPermissions = mutableListOf<String>()
+ permissions.forEach { permission ->
+ when (permission) {
+ is ContentVideoCamera, is ContentVideoCapture -> {
+ systemPermissions.add(CAMERA)
+ }
+ is ContentAudioCapture, is ContentAudioMicrophone -> {
+ systemPermissions.add(RECORD_AUDIO)
+ }
+ else -> {
+ // no-op
+ }
+ }
+ }
+ return systemPermissions.all { context.isPermissionGranted((it)) }
+ }
+
+ data class PromptsStyling(
+ val gravity: Int,
+ val shouldWidthMatchParent: Boolean = false,
+ @ColorRes
+ val positiveButtonBackgroundColor: Int? = null,
+ @ColorRes
+ val positiveButtonTextColor: Int? = null,
+ )
+
+ /**
+ * Customization options for feature request dialog
+ */
+ data class DialogConfig(
+ /** Use **true** to pre-select "Do not ask again" checkbox. */
+ val shouldPreselectDoNotAskAgain: Boolean = false,
+ ) {
+
+ companion object {
+ /** Default values for [DialogConfig.shouldPreselectDoNotAskAgain] */
+ internal const val DEFAULT_PRESELECT_DO_NOT_ASK_AGAIN = false
+ }
+ }
+
+ /**
+ * Re-attaches a fragment that is still visible but not linked to this feature anymore.
+ */
+ private fun reattachFragment(fragment: SitePermissionsDialogFragment) {
+ val currentTab = store.state.findTabOrCustomTabOrSelectedTab(fragment.sessionId)?.content
+ if (currentTab == null || (noPermissionRequests(currentTab))) {
+ fragmentManager.beginTransaction()
+ .remove(fragment)
+ .commitAllowingStateLoss()
+ } else {
+ // Re-assign the feature instance so that the fragment can invoke us once the
+ // user makes a selection or cancels the dialog.
+ fragment.feature = this
+ }
+ }
+
+ @VisibleForTesting
+ internal fun noPermissionRequests(contentState: ContentState) =
+ contentState.appPermissionRequestsList.isEmpty() &&
+ contentState.permissionRequestsList.isEmpty()
+}
+
+internal fun SitePermissions?.isGranted(permissionRequest: PermissionRequest): Boolean {
+ return if (this != null) {
+ permissionRequest.permissions.all { permission ->
+ isPermissionGranted(permission, this)
+ }
+ } else {
+ false
+ }
+}
+
+@VisibleForTesting
+internal fun isPermissionGranted(
+ permission: Permission,
+ permissionFromStorage: SitePermissions,
+): Boolean {
+ return when (permission) {
+ is ContentGeoLocation -> {
+ permissionFromStorage.location.isAllowed()
+ }
+ is ContentNotification -> {
+ permissionFromStorage.notification.isAllowed()
+ }
+ is ContentAudioCapture, is ContentAudioMicrophone -> {
+ permissionFromStorage.microphone.isAllowed()
+ }
+ is ContentVideoCamera, is ContentVideoCapture -> {
+ permissionFromStorage.camera.isAllowed()
+ }
+ is ContentPersistentStorage -> {
+ permissionFromStorage.localStorage.isAllowed()
+ }
+ is ContentCrossOriginStorageAccess -> {
+ permissionFromStorage.crossOriginStorageAccess.isAllowed()
+ }
+ is ContentMediaKeySystemAccess -> {
+ permissionFromStorage.mediaKeySystemAccess.isAllowed()
+ }
+ is ContentAutoPlayAudible -> {
+ permissionFromStorage.autoplayAudible.isAllowed()
+ }
+ is ContentAutoPlayInaudible -> {
+ permissionFromStorage.autoplayInaudible.isAllowed()
+ }
+ else ->
+ throw InvalidParameterException("$permission is not a valid permission.")
+ }
+}
+
+private fun Permission.isSupported(): Boolean {
+ return when (this) {
+ is ContentGeoLocation,
+ is ContentNotification,
+ is ContentPersistentStorage,
+ is ContentCrossOriginStorageAccess,
+ is ContentAudioCapture, is ContentAudioMicrophone,
+ is ContentVideoCamera, is ContentVideoCapture,
+ is ContentAutoPlayAudible, is ContentAutoPlayInaudible,
+ is ContentMediaKeySystemAccess,
+ -> true
+ else -> false
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt
new file mode 100644
index 0000000000..a58d50da15
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsRules.kt
@@ -0,0 +1,126 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import mozilla.components.concept.engine.permission.Permission
+import mozilla.components.concept.engine.permission.PermissionRequest
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ASK_TO_ALLOW
+import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.BLOCKED
+
+/**
+ * Indicate how site permissions must behave by permission category.
+ */
+data class SitePermissionsRules constructor(
+ val camera: Action,
+ val location: Action,
+ val notification: Action,
+ val microphone: Action,
+ val autoplayAudible: AutoplayAction,
+ val autoplayInaudible: AutoplayAction,
+ val persistentStorage: Action,
+ val mediaKeySystemAccess: Action,
+ val crossOriginStorageAccess: Action,
+) {
+
+ enum class Action {
+ ALLOWED, BLOCKED, ASK_TO_ALLOW;
+
+ fun toStatus(): SitePermissions.Status = when (this) {
+ ALLOWED -> SitePermissions.Status.ALLOWED
+ BLOCKED -> SitePermissions.Status.BLOCKED
+ ASK_TO_ALLOW -> SitePermissions.Status.NO_DECISION
+ }
+ }
+
+ /**
+ * Autoplay requests will never prompt the user
+ */
+ enum class AutoplayAction {
+ ALLOWED, BLOCKED;
+
+ internal fun toAction(): Action = when (this) {
+ ALLOWED -> Action.ALLOWED
+ BLOCKED -> Action.BLOCKED
+ }
+
+ /**
+ * Convert from an AutoplayAction to an AutoplayStatus.
+ */
+ fun toAutoplayStatus(): AutoplayStatus = when (this) {
+ ALLOWED -> AutoplayStatus.ALLOWED
+ BLOCKED -> AutoplayStatus.BLOCKED
+ }
+ }
+
+ internal fun getActionFrom(request: PermissionRequest): Action {
+ return if (request.containsVideoAndAudioSources()) {
+ getActionForCombinedPermission()
+ } else {
+ getActionForSinglePermission(request.permissions.first())
+ }
+ }
+
+ private fun getActionForSinglePermission(permission: Permission): Action {
+ return when (permission) {
+ is Permission.ContentGeoLocation -> {
+ location
+ }
+ is Permission.ContentNotification -> {
+ notification
+ }
+ is Permission.ContentPersistentStorage -> {
+ persistentStorage
+ }
+ is Permission.ContentAudioCapture, is Permission.ContentAudioMicrophone -> {
+ microphone
+ }
+ is Permission.ContentVideoCamera, is Permission.ContentVideoCapture -> {
+ camera
+ }
+ is Permission.ContentAutoPlayAudible -> {
+ autoplayAudible.toAction()
+ }
+ is Permission.ContentAutoPlayInaudible -> {
+ autoplayInaudible.toAction()
+ }
+ is Permission.ContentMediaKeySystemAccess -> {
+ mediaKeySystemAccess
+ }
+ is Permission.ContentCrossOriginStorageAccess -> {
+ crossOriginStorageAccess
+ }
+ else -> ASK_TO_ALLOW
+ }
+ }
+
+ private fun getActionForCombinedPermission(): Action {
+ return if (camera == BLOCKED || microphone == BLOCKED) {
+ BLOCKED
+ } else {
+ ASK_TO_ALLOW
+ }
+ }
+
+ /**
+ * Converts a [SitePermissionsRules] object into a [SitePermissions] .
+ */
+ fun toSitePermissions(origin: String, savedAt: Long = System.currentTimeMillis()): SitePermissions {
+ return SitePermissions(
+ origin = origin,
+ location = location.toStatus(),
+ notification = notification.toStatus(),
+ microphone = microphone.toStatus(),
+ camera = camera.toStatus(),
+ autoplayAudible = autoplayAudible.toAutoplayStatus(),
+ autoplayInaudible = autoplayInaudible.toAutoplayStatus(),
+ localStorage = persistentStorage.toStatus(),
+ mediaKeySystemAccess = mediaKeySystemAccess.toStatus(),
+ crossOriginStorageAccess = crossOriginStorageAccess.toStatus(),
+ savedAt = savedAt,
+ )
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDao.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDao.kt
new file mode 100644
index 0000000000..75f828aae4
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDao.kt
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions.db
+
+import androidx.paging.DataSource
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.Query
+import androidx.room.Update
+
+/**
+ * Internal dao for accessing and modifying sitePermissions in the database.
+ */
+@Dao
+internal interface SitePermissionsDao {
+
+ @Insert
+ fun insert(entity: SitePermissionsEntity): Long
+
+ @Update
+ fun update(entity: SitePermissionsEntity)
+
+ @Query("SELECT * FROM site_permissions ORDER BY saved_at DESC")
+ fun getSitePermissions(): List<SitePermissionsEntity>
+
+ @Query("SELECT * FROM site_permissions where origin =:origin LIMIT 1")
+ fun getSitePermissionsBy(origin: String): SitePermissionsEntity?
+
+ @Delete
+ fun deleteSitePermissions(entity: SitePermissionsEntity)
+
+ @Query("DELETE FROM site_permissions")
+ fun deleteAllSitePermissions()
+
+ @Query("SELECT * FROM site_permissions ORDER BY saved_at DESC")
+ fun getSitePermissionsPaged(): DataSource.Factory<Int, SitePermissionsEntity>
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt
new file mode 100644
index 0000000000..bdf82b53e5
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsDatabase.kt
@@ -0,0 +1,189 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions.db
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverter
+import androidx.room.TypeConverters
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+import mozilla.components.concept.engine.permission.SitePermissions
+
+/**
+ * Internal database for saving site permissions.
+ */
+@Database(entities = [SitePermissionsEntity::class], version = 8)
+@TypeConverters(StatusConverter::class)
+internal abstract class SitePermissionsDatabase : RoomDatabase() {
+ abstract fun sitePermissionsDao(): SitePermissionsDao
+
+ companion object {
+ @Volatile
+ private var instance: SitePermissionsDatabase? = null
+
+ @Synchronized
+ fun get(context: Context): SitePermissionsDatabase {
+ instance?.let { return it }
+
+ return Room.databaseBuilder(
+ context,
+ SitePermissionsDatabase::class.java,
+ "site_permissions_database",
+ ).addMigrations(
+ Migrations.migration_1_2,
+ ).addMigrations(
+ Migrations.migration_2_3,
+ ).addMigrations(
+ Migrations.migration_3_4,
+ ).addMigrations(
+ Migrations.migration_4_5,
+ ).addMigrations(
+ Migrations.migration_5_6,
+ ).addMigrations(
+ Migrations.migration_6_7,
+ ).addMigrations(
+ Migrations.migration_7_8,
+ ).build().also { instance = it }
+ }
+ }
+}
+
+@Suppress("unused")
+internal class StatusConverter {
+ private val autoplayStatusArray = SitePermissions.AutoplayStatus.values()
+
+ private val statusArray = SitePermissions.Status.values()
+
+ @TypeConverter
+ fun toInt(status: SitePermissions.Status): Int {
+ return status.id
+ }
+
+ @TypeConverter
+ fun toStatus(index: Int): SitePermissions.Status? {
+ return statusArray.find { it.id == index }
+ }
+
+ @TypeConverter
+ fun toInt(status: SitePermissions.AutoplayStatus): Int {
+ return status.id
+ }
+
+ @TypeConverter
+ fun toAutoplayStatus(index: Int): SitePermissions.AutoplayStatus {
+ return autoplayStatusArray.find { it.id == index } ?: SitePermissions.AutoplayStatus.BLOCKED
+ }
+}
+
+internal object Migrations {
+ val migration_1_2 = object : Migration(1, 2) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ // Version 1 is used in Nightly builds of Fenix, but not in production. Let's just skip actually migrating
+ // anything and let's re-create the "site_permissions" table.
+
+ db.execSQL("DROP TABLE site_permissions")
+ db.execSQL(
+ "CREATE TABLE IF NOT EXISTS `site_permissions` (" +
+ "`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, " +
+ "`saved_at` INTEGER NOT NULL," +
+ " PRIMARY KEY(`origin`))",
+ )
+ }
+ }
+
+ @Suppress("MagicNumber")
+ val migration_2_3 = object : Migration(2, 3) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ val haveAutoPlayColumns = db.query("SELECT * FROM site_permissions").columnCount == 10
+ // We just want to apply this migration for user that do not have
+ // the new autoplay fields autoplay_audible and autoplay_inaudible
+ if (!haveAutoPlayColumns) {
+ db.execSQL(
+ "ALTER TABLE site_permissions ADD COLUMN autoplay_audible INTEGER NOT NULL DEFAULT ''",
+ )
+ db.execSQL(
+ "ALTER TABLE site_permissions ADD COLUMN autoplay_inaudible INTEGER NOT NULL DEFAULT ''",
+ )
+
+ db.execSQL(
+ " UPDATE site_permissions" +
+ " SET autoplay_audible = -1, " + // BLOCKED by default
+ " `autoplay_inaudible` = 1", // ALLOWED by default
+ )
+ }
+ }
+ }
+
+ @Suppress("MagicNumber")
+ val migration_3_4 = object : Migration(3, 4) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ val hasEmeColumn = db.query("SELECT * FROM site_permissions").columnCount == 11
+ if (!hasEmeColumn) {
+ db.execSQL(
+ "ALTER TABLE site_permissions ADD COLUMN media_key_system_access INTEGER NOT NULL DEFAULT 0",
+ )
+ // default is NO_DECISION
+ db.execSQL("UPDATE site_permissions SET media_key_system_access = 0")
+ }
+ }
+ }
+
+ @Suppress("MagicNumber")
+ val migration_4_5 = object : Migration(4, 5) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ // Updating any previous autoplay sites with 0 (NO_DECISION) with the supported values
+ // Autoplay permission doesn't support 0 (NO_DECISION),
+ // it only supports 1 (ALLOWED) or -1 (BLOCKED)
+ db.execSQL("UPDATE site_permissions SET autoplay_audible = -1 WHERE autoplay_audible = 0 ")
+ db.execSQL("UPDATE site_permissions SET autoplay_inaudible = 1 WHERE autoplay_inaudible = 0 ")
+ }
+ }
+
+ @Suppress("MagicNumber")
+ val migration_5_6 = object : Migration(5, 6) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ db.execSQL(
+ "UPDATE site_permissions SET origin = 'https://'||origin||':443'",
+ )
+ }
+ }
+
+ @Suppress("MagicNumber")
+ val migration_6_7 = object : Migration(6, 7) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ // Update any site with our previous default value (block audio and video) to block audio only.
+ // autoplay_audible BLOCKED (-1) and autoplay_inaudible BLOCKED (-1) to
+ // autoplay_audible BLOCKED (-1) and autoplay_inaudible ALLOWED (1)
+ // This match the default value of desktop block audio only.
+ db.execSQL(
+ "UPDATE site_permissions SET autoplay_audible = -1, autoplay_inaudible= 1 " +
+ "WHERE autoplay_audible = -1 AND autoplay_inaudible = -1",
+ )
+ }
+ }
+
+ @Suppress("MagicNumber")
+ val migration_7_8 = object : Migration(7, 8) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ val hasCrossOriginStorageAccessColumn = db.query("SELECT * FROM site_permissions").columnCount == 12
+ if (!hasCrossOriginStorageAccessColumn) {
+ db.execSQL(
+ "ALTER TABLE site_permissions ADD COLUMN cross_origin_storage_access INTEGER NOT NULL DEFAULT 0",
+ )
+ // default is NO_DECISION
+ db.execSQL("UPDATE site_permissions SET cross_origin_storage_access = 0")
+ }
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt
new file mode 100644
index 0000000000..39346ebab0
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/db/SitePermissionsEntity.kt
@@ -0,0 +1,89 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions.db
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import mozilla.components.concept.engine.permission.SitePermissions
+
+/**
+ * Internal entity representing a site permission as it gets saved to the database.
+ */
+@Entity(tableName = "site_permissions")
+internal data class SitePermissionsEntity(
+
+ @PrimaryKey
+ @ColumnInfo(name = "origin")
+ var origin: String,
+
+ @ColumnInfo(name = "location")
+ var location: SitePermissions.Status,
+
+ @ColumnInfo(name = "notification")
+ var notification: SitePermissions.Status,
+
+ @ColumnInfo(name = "microphone")
+ var microphone: SitePermissions.Status,
+
+ @ColumnInfo(name = "camera")
+ var camera: SitePermissions.Status,
+
+ @ColumnInfo(name = "bluetooth")
+ var bluetooth: SitePermissions.Status,
+
+ @ColumnInfo(name = "local_storage")
+ var localStorage: SitePermissions.Status,
+
+ @ColumnInfo(name = "autoplay_audible")
+ var autoplayAudible: SitePermissions.AutoplayStatus,
+
+ @ColumnInfo(name = "autoplay_inaudible")
+ var autoplayInaudible: SitePermissions.AutoplayStatus,
+
+ @ColumnInfo(name = "media_key_system_access")
+ var mediaKeySystemAccess: SitePermissions.Status,
+
+ @ColumnInfo(name = "cross_origin_storage_access")
+ var crossOriginStorageAccess: SitePermissions.Status,
+
+ @ColumnInfo(name = "saved_at")
+ var savedAt: Long,
+) {
+
+ internal fun toSitePermission(): SitePermissions {
+ return SitePermissions(
+ origin,
+ location,
+ notification,
+ microphone,
+ camera,
+ bluetooth,
+ localStorage,
+ autoplayAudible,
+ autoplayInaudible,
+ mediaKeySystemAccess,
+ crossOriginStorageAccess,
+ savedAt,
+ )
+ }
+}
+
+internal fun SitePermissions.toSitePermissionsEntity(): SitePermissionsEntity {
+ return SitePermissionsEntity(
+ origin,
+ location,
+ notification,
+ microphone,
+ camera,
+ bluetooth,
+ localStorage,
+ autoplayAudible,
+ autoplayInaudible,
+ mediaKeySystemAccess,
+ crossOriginStorageAccess,
+ savedAt,
+ )
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/layout/mozac_site_permissions_prompt.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/layout/mozac_site_permissions_prompt.xml
new file mode 100644
index 0000000000..482205f133
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/layout/mozac_site_permissions_prompt.xml
@@ -0,0 +1,127 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?android:windowBackground"
+ android:orientation="vertical"
+ tools:ignore="Overdraw">
+
+ <androidx.appcompat.widget.AppCompatImageView
+ android:id="@+id/icon"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_alignParentTop="true"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="16dp"
+ android:importantForAccessibility="no"
+ android:scaleType="center"
+ app:tint="?android:attr/textColorPrimary"
+ tools:src="@android:drawable/ic_menu_camera"
+ tools:tint="#000000" />
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@id/icon"
+ android:layout_alignParentTop="true"
+ android:layout_marginStart="3dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginEnd="11dp"
+ android:layout_toEndOf="@id/icon"
+ android:paddingStart="5dp"
+ android:paddingTop="4dp"
+ android:paddingEnd="5dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="16sp"
+ tools:text="Allow wikipedia.org to use your camera?"
+ tools:textColor="#000000" />
+
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/title"
+ android:layout_alignStart="@id/title"
+ android:layout_marginStart="3dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="11dp"
+ android:layout_toEndOf="@id/icon"
+ android:paddingStart="5dp"
+ android:paddingTop="4dp"
+ android:paddingEnd="5dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="16sp"
+ tools:text="This is a message offering more context about the permission."
+ tools:textColor="#000000"
+ android:visibility="gone"
+ tools:visibility="visible"/>
+
+ <TextView
+ android:id="@+id/learn_more"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/message"
+ android:layout_alignStart="@id/title"
+ android:layout_marginStart="3dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginEnd="11dp"
+ android:layout_toEndOf="@id/icon"
+ android:paddingStart="5dp"
+ android:paddingTop="4dp"
+ android:paddingEnd="5dp"
+ android:text="@string/mozac_feature_sitepermissions_learn_more_title"
+ android:textColor="?android:attr/textColorLink"
+ android:textSize="16sp"
+ android:visibility="gone"
+ tools:visibility="visible" />
+
+ <CheckBox
+ android:id="@+id/do_not_ask_again"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/learn_more"
+ android:layout_alignStart="@id/title"
+ android:layout_marginTop="2dp"
+ android:checked="true"
+ android:paddingStart="0dp"
+ android:paddingTop="18dp"
+ android:paddingBottom="14dp"
+ android:paddingEnd="4dp"
+ android:text="@string/mozac_feature_sitepermissions_do_not_ask_again_on_this_site2"
+ android:textColor="?android:attr/textColorPrimary"
+ android:visibility="gone"
+ tools:visibility="visible" />
+
+ <Button
+ android:id="@+id/deny_button"
+ style="?android:attr/borderlessButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/do_not_ask_again"
+ android:layout_marginTop="2dp"
+ android:layout_toStartOf="@id/allow_button"
+ android:text="@string/mozac_feature_sitepermissions_not_allow"
+ android:textAlignment="center"
+ android:textAllCaps="false" />
+
+ <Button
+ android:id="@+id/allow_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/do_not_ask_again"
+ android:layout_alignParentEnd="true"
+ android:layout_marginStart="8dp"
+ android:layout_marginTop="2dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginBottom="16dp"
+ android:text="@string/mozac_feature_sitepermissions_allow"
+ android:textAlignment="center"
+ android:textAllCaps="false" />
+
+</RelativeLayout> \ No newline at end of file
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-am/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-am/strings.xml
new file mode 100644
index 0000000000..6c6af28974
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-am/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s ማሳወቂያዎችን እንዲልክ ይፈቀድለት?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s ካሜራዎን እንዲጠቀም ይፈቀድለት?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s ማይክሮፎንዎን እንዲጠቀም ይፈቀድለት?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s አካባቢዎን እንዲጠቀም ይፈቀድለት?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s የእርስዎን ካሜራ እና ማይክሮፎን እንዲጠቀም ይፈቀድለት?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ማይክሮፎን 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">የኋላ ካሜራ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">የፊት ካሜራ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ፍቀድ</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">አትፍቀድ</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">የዚህን ድረ-ገፅ ውሳኔ አስታውስ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ሁሌም</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">በፍጹም</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s በቋሚ ማከማቻ ውስጥ ውሂብ እንዲያከማች ይፈቀድለት?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s በDRM የሚቆጣጠረውን ይዘት እንዲያጫውት ይፈቀድለት?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s ኩኪዎቹን በ%2$s ላይ እንዲጠቀም ይፈቀድለት?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s ለምን ይህ ውሂብ እንደሚያስፈልገው ግልጽ ካልሆነ መዳረሻን ማገድ ይፈልጉ ይሆናል።</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">አግድ</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ተጨማሪ ይወቁ</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-an/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-an/strings.xml
new file mode 100644
index 0000000000..1d2fffe064
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-an/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permitir que %1$s ninvie notificacions?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permitir que %1$s emplegue la tuya camara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permitir que %1$s emplegue lo tuyo microfono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permitir que %1$s emplege la tuya localización?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permitir que %1$s emplegue la camara y lo microfono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Camara zaguera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Camara debantera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recordar la decisión pa este puesto</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Siempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ar/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ar/strings.xml
new file mode 100644
index 0000000000..9447cec41d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ar/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">أتسمح بأن يُرسل %1$s التنبيهات؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">أتسمح بأن يستعمل %1$s الكمرة؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">أتسمح بأن يستعمل %1$s الميكروفون؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">أتسمح بأن يستعمل %1$s مكانك؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">أستسمح بأن يستعمل %1$s الكمرة والميكروفون؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ميكروفون 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">الكمرة الخلفية</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">الكمرة الأمامية</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">اسمح</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">لا تسمح</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">تذكّر هذا القرار لهذا الموقع</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">دائمًا</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">أبدًا</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">هل تسمح أي يحفظ %1$s بيانات في مساحة تخزين دائما؟</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">هل تسمح بأن يُشغّل %1$s محتوى خاضع لإدارة الحقوق الرقمية؟</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">أتسمح بأن يستعمل %1$s كعكاته على %2$s؟</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">يمكنك حجب الوصول إليها إن لم يكن السبب وراء احتياج %s لهذه البيانات واضحًا.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">احجب</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">اطّلع على المزيد</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ast/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ast/strings.xml
new file mode 100644
index 0000000000..1a4f8a717a
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ast/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">¿Quies permitir a «%1$s» qu\'unvie avisos?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">¿Quies permitir a «%1$s» qu\'use la cámara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">¿Quies permitir a «%1$s» qu\'use\'l micrófonu?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">¿Quies permitir a «%1$s» qu\'use la to llocalización?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">¿Quies permitir a «%1$s» qu\'use la cámara ya\'l micrófonu?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrófonu 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cámara d\'atrás</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cámara d\'alantre</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Nun permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recordar la decisión pa esti sitiu</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Siempres</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Enxamás</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿Quies permitir a «%1$s» qu\'atroxe datos nel almacenamientu permanente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿Quies permitir a «%1$s» que reproduza conteníu con DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿Quies permitir a «%1$s» qu\'use les sos cookies en «%2$s»?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Si nun ta claro por qué «%s» precisa estos datos, ye probable que quieras bloquiar l\'accesu.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquiar</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saber más</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-az/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-az/strings.xml
new file mode 100644
index 0000000000..673643b1e9
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-az/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s bildiriş göndərə bilsin?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s kameranızı işlədə bilsin?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s mikrofonunuzu işlədə bilsin?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s mövqeyinizi işlədə bilsin?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s kamera və mikrofonunuzu işlədə bilsin?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Arxa kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Ön kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">İcazə ver</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">İcazə vermə</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Seçimi bu sayt üçün yadda saxla</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Hər zaman</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Heç vaxt</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s üçün qalıcı yaddaşda məlumat saxlamağa icazə verilsin?</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml
new file mode 100644
index 0000000000..26d646b790
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-azb/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s بیلدیریش گؤندره ‌بیلسین؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s کامئرازی ایشه آلسین؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s میکروفونوزو ایشه آلسین؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s قونوموزو ایشه آلسین؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s کامئرا و میکروفونوزو ایشه آلسین؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">میکروفون</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">سلفی کامئرا</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">قاباق کامئرا</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ایجازه وئر</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ایجازه وئرمه</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">بو سایت اوچون قراری یاددا ساخلا</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">هر زامان</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">هئچ زامان</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s قالیجی مخزنینده دیتا ساخلیا بیلسین؟</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s سایتی DRM-کونترول موحتوالاری اوینادا بیلسین؟</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s، کوکی‌لرینی %2$s سایتیندا ایشه آلسین؟</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s سایتینین بو دیتایا نیه احتیاج اولدوغونو بیلمیرسیز ال‌چاتمانی مسدود ائلیه بیلرسیز.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">مسدود ائله</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">آرتیق بیلین</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-be/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-be/strings.xml
new file mode 100644
index 0000000000..9494effbb7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-be/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Дазволіць %1$s адпраўляць вам абвесткі?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Дазволіць %1$s выкарыстоўваць вашу камеру?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Дазволіць %1$s выкарыстоўваць ваш мікрафон?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Дазволіць %1$s выкарыстоўваць ваша месцазнаходжанне?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Дазволіць %1$s выкарыстоўваць вашу камеру і мікрафон?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Мікрафон 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Задняя камера</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Пярэдняя камера</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Дазволіць</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Не дазваляць</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Памятаць рашэнне для гэтага сайта</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Заўсёды</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Ніколі</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Дазволіць %1$s захоўваць дадзеныя ў пастаянным сховішчы?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Дазволіць %1$s прайграваць змесціва, якое кантралюецца DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Дазволіць %1$s выкарыстоўваць свае кукi на %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Вы можаце заблакаваць доступ, калі няясна, навошта %s патрэбны гэтыя дадзеныя.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Блакаваць</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Падрабязней</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bg/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bg/strings.xml
new file mode 100644
index 0000000000..825e5fefe9
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bg/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Разрешение %1$s да изпраща известия?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Разрешение %1$s да използва камера?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Разрешение %1$s да използва микрофон?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Разрешение %1$s да използва местоположение?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Разрешение %1$s да използва камера и микрофон?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Микрофон 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Задна камера</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Предна камера</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Разрешаване</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Забраняване</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Запомняне на решение за страницата</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Винаги</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Никога</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Разрешение %1$s да запазва в постоянно хранилище?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Разрешение %1$s да възпроизвежда контролирано с DRM съдържание?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Разрешение на %1$s да използва бисквитки в %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Бихте могли да забраните ако не ясно защо %s се нуждае то тези данни.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Забраняване</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Научете повече</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bn/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bn/strings.xml
new file mode 100644
index 0000000000..92b56c412e
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bn/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s কে বিজ্ঞপ্তি পাঠানোর অনুমতি দিবেন?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s কে আপনার ক্যামেরা ব্যবহার করার অনুমতি দিবেন?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s কে আপনার মাইক্রোফোন ব্যবহার করার অনুমতি দিবেন?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s কে আপনার অবস্থান ব্যবহার করার অনুমতি দিবেন?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s কে আপনার ক্যামেরা এবং মাইক্রোফোন ব্যবহার করার অনুমতি দিবেন?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">মাইক্রোফোন 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">পিছনের দিকের ক্যামেরা</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">সামনের দিকের ক্যামেরা</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">অনুমতি দিন</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">অনুমতি দিবেন না</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">এই সাইটের জন্য সিদ্ধান্ত মনে রাখুন</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">সবসময়</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">কখনো না</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$sকে স্থায়ী স্টোরেজে তথ্য রাখতে দিবে?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$sকে ডিআরএম-নিয়ন্ত্রিত মিডিয়া প্লে করতে দিবে?</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-br/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-br/strings.xml
new file mode 100644
index 0000000000..d74d4f03f7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-br/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Aotren %1$s da gas rebuzadurioù deocʼh?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Aotren %1$s da arverañ ho kamera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Aotren %1$s da arverañ ho klevell?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Aotren %1$s da arverañ ho lecʼhiadur?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Aotren %1$s da arverañ ho kamera hag ho klevell?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Klevell 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kamera a-dreñv</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kamera a-dal</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Aotren</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Na aotren</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Dercʼhel soñj eus an dibab-se evit al lecʼhienn-mañ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Atav</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Morse</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Aotren %1$s da gadaviñ roadennoù er c’hadaviñ diastal?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Aotren %1$s da lenn endalc’had reoliet gant DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Aotren %1$s da implij he zoupinoù war %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Gallout a rafec’h kaout c’hoant nac’hañ ma n’eo ket sklaer perak e fell da %s kaout ar roadennoù-mañ.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Stankañ</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Gouzout hiroc’h</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bs/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bs/strings.xml
new file mode 100644
index 0000000000..474c1fae0f
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-bs/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Dozvoliti da %1$s šalje obavijesti?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Dozvoliti da %1$s koristi vašu kameru?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Dozvoliti da %1$s koristi vaš mikrofon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Dozvoliti da %1$s koristi vašu lokaciju?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Dozvoliti da %1$s koristi vašu kameru i mikrofon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Zadnja kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Prednja kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Dozvoli</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ne dozvoli</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Zapamti odluku za ovu stranicu</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Uvijek</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nikad</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Dozvoli %1$s da čuva informacije u trajnom skladištu?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Dozvoli %1$s da pušta DRM-kontrolisani sadržaj?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Dozvoli %1$s da koristi svoje kolačiće na %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Možda želite blokirati pristup ako nije jasno zašto %s treba ove podatke.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokiraj</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saznajte više</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ca/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ca/strings.xml
new file mode 100644
index 0000000000..a01e196433
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ca/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Voleu permetre que %1$s enviï notificacions?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Voleu permetre que %1$s utilitzi la càmera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Voleu permetre que %1$s utilitzi el micròfon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Voleu permetre que %1$s utilitzi la vostra ubicació?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Voleu permetre que %1$s utilitzi la càmera i el micròfon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micròfon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Càmera posterior</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Càmera frontal</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permet</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No ho permetis</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recorda la decisió per a aquest lloc</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Sempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Voleu permetre que %1$s desi dades en l’emmagatzematge persistent?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Voleu permetre que %1$s reprodueixi contingut controlat per DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Voleu permetre que %1$s utilitzi galetes en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Si no teniu clar per què %s necessita aquestes dades, podeu blocar-ne l’accés.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloca</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Més informació</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cak/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cak/strings.xml
new file mode 100644
index 0000000000..412099cbd1
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cak/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">¿La niya\' q\'ij chi ri %1$s yerutäq taq rutzijol?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">¿La niya\' q\'ij chi re ri %1$s richin nrokisaj ri elesäy wachib\'äl?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">¿La niya\' q\'ij chi re ri %1$s richin nrokisaj ri q\asäy ch\'ab\'äl?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">¿La niya\' q\'ij chi re ri %1$s richin nrokisaj ri ak\'ojlemal?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">¿La niya\' q\'ij chi re ri %1$s richin nrokisaj ri elsäy wachib\'äl chuqa\' q\'asäy ch\'ab\'äl?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Q\'asäy ch\'ab\'äl 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Rij elesäy wachib\'äl</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Ruwäch elesäy wachib\'äl</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Tiya\' q\'ij</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Man tiya\' q\'ij</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Tinatäx ri xna\'ojïx pa re ruxaq re\'</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Junelïk</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Majub\'ey</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿La niya\' q\'ij chi ri %1$s keruyaka\' taq tzij pa jutaqil yakoj?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿La niya\' q\'ij chi ri %1$s nutzïj rupam samajin ruma DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿La niya\' q\'ij chi ri %1$s? kerokisaj taq kuki pa %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Rik\'in jub\'a\' nawajo\' naq\'ät ri okem we man q\'aläj ta ruma chi ri %s nik\'atzin chi re re taq tzij re\'.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Tiq\'at</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Tetamäx ch\'aqa\' chik</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ceb/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ceb/strings.xml
new file mode 100644
index 0000000000..031b0dddcd
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ceb/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Tugotan ang %1$s magsend ug notifications?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Tugotan ang %1$s mogamit ug camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Tugotan ang %1$s nga mogamit ug microphone?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Tugotan ang %1$s nga mogamit sa imong location?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Tugotan ang %1$s nga gamiton imong camera ug microphone?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microphone</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Likod nga camera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Atbang nga camera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Tugotan</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ayaw tugoti</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Hinumdomi ang desisyon ni ini nga site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Kanunay</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Dili</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Tugotan ang %1$s magbutang ug data sa permanent storage</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Tugotan ang %1$s mag play ang DRM controlled content?</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ckb/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ckb/strings.xml
new file mode 100644
index 0000000000..cf7756aa51
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ckb/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">ڕێگەدەدەیت %1$s ئاگانامە بنێرێت بۆت؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">ڕێگەدەدەیت %1$s کامێراکەت بەکاربێنێ؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">رێگەدەدەیت %1$s مایکرۆفۆنەکەت بەکاربێنێت؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">ڕێگەدەدەیت %1$s شوێنەکەت بەکاربێنێت؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">ڕێگەدەدەیت %1$s کامێرا و مایکرۆفۆنەکەت بەکاربێنێ؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">مایکرۆفۆن 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">کامێرای دوواوە</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">کامێرای پێشەوە</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ڕێگەبدە</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ڕێگە مەدە</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">بڕیارەکەت بیربێت بۆ ئەم ماڵپەڕە</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">هەمووکات</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">هیچ کات</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">ڕێگەدەدەیت کە %1$s زانیاری پاشەکەوتبکات لە بیرگەی هەمیشەیی؟</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">ڕێگەدەدەیت کە %1$s ناوەڕۆکی پارێزراوی ژمارەیی DRM لێبدات؟</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-co/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-co/strings.xml
new file mode 100644
index 0000000000..2810bb03c9
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-co/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permette à %1$s di mandà nutificazioni ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permette à %1$s d’impiegà u vostru apparechju-fotò ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permette à %1$s d’impiegà u vostru microfonu ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permette à %1$s d’accede à a vostra lucalizazione ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permette à %1$s d’impiegà u vostru apparechju-fotò è u vostru microfonu ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfonu 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Apparechju-fotò daretu</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Apparechju-fotò davanti</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permette</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ùn permette micca</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Arricurdassi di sta scelta per stu situ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Sempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Permette à %1$s d’allucà dati in a memoria permanente ?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permette à %1$s di leghje cuntenutu cuntrollatu da DRM ?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permette à %1$s d’impiegà i so canistrelli nant’à %2$s ?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Forse preferite bluccà l’accessu s’ellu ùn hè micca chjaru perchè %s abbia bisognu di sti dati.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bluccà</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Sapene di più</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cs/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cs/strings.xml
new file mode 100644
index 0000000000..4222f12df7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cs/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Chcete serveru %1$s povolit zasílat vám oznámení?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Chcete serveru %1$s povolit používat vaši kameru?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Chcete serveru %1$s povolit používat váš mikrofon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Chcete serveru %1$s povolit přístup k vaší poloze?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Chcete serveru %1$s povolit používat vaši kameru a mikrofon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Zadní kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Přední kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Povolit</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Nepovolit</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Pamatovat si pro tento server</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Vždy</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nikdy</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Chcete povolit serveru %1$s ukládat data natrvalo?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Chcete serveru %1$s povolit přehrávat obsah chráněný pomocí DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Povolit serveru %1$s používat své cookies také na serveru %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Pokud není jasné, proč server %s tato data potřebuje, nejspíše můžete jeho požadavek zablokovat.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokovat</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Zjistit více</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml
new file mode 100644
index 0000000000..e937f6fc0a
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-cy/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Caniatáu i %1$s anfon hysbysiadau?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Caniatáu i%1$s ddefnyddio’ch camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Caniatáu i %1$s ddefnyddio’ch camera?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Caniatáu i %1$s ddefnyddio’ch camera?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Caniatáu i %1$s ddefnyddio eich camera a’ch meicroffon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Meicroffon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Camera’n wynebu nôl</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Camera’n wynebu ymlaen</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Caniatáu</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Peidio â chaniatáu</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Cofio’r penderfyniad am y wefan hon</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Bob tro</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Byth</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Caniatáu i %1$s storio data mewn storfa barhaus?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Caniatáu i %1$s chwarae cynnwys sy’n cael ei reoli gan DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Caniatáu i %1$s ddefnyddio ei gwcis ar %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Efallai y byddwch am rwystro mynediad os nad yw’n glir pam mae angen y data hwn ar %s.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Rhwystro</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Darllen rhagor</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-da/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-da/strings.xml
new file mode 100644
index 0000000000..5c7b31b5a8
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-da/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Vil du give %1$s lov til at sende meddelelser?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Vil du give %1$s lov til at anvende dit kamera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Vil du give %1$s lov til at anvende din mikrofon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Vil du give %1$s lov til at anvende din position?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Vil du give %1$s lov til at anvende dit kamera og din mikrofon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Bagudrettet kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Fremadrettet kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Tillad</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Tillad ikke</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Husk mit valg for dette websted</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Altid</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Aldrig</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Vil du give %1$s lov til at gemme data i vedvarende lager?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Vil du give %1$s love til at afspille DRM-kontrolleret indhold?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Tillad %1$s at bruge sine cookies på %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Overvej at blokere adgangen, hvis det ikke er tydeligt, hvorfor %s behøver disse data.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloker</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Læs mere</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-de/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-de/strings.xml
new file mode 100644
index 0000000000..cee0c058d0
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-de/strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s erlauben, Benachrichtigungen zu senden?</string>
+
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s erlauben, Ihre Kamera zu verwenden?</string>
+
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s erlauben, Ihr Mikrofon zu verwenden?</string>
+
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s erlauben, Ihren Standort zu verwenden?</string>
+
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s erlauben, Ihre Kamera und Ihr Mikrofon zu verwenden?</string>
+
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kamera Rückseite</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kamera Vorderseite</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Erlauben</string>
+
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Nicht erlauben</string>
+
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Diese Entscheidung für diese Website merken</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Immer</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nie</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Soll %1$s Daten im dauerhaften Speicher speichern dürfen?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s die Wiedergabe von DRM-kontrollierten Inhalten erlauben?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s erlauben, seine Cookies auf %2$s zu verwenden?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Möglicherweise möchten Sie den Zugriff blockieren, wenn nicht klar ist, warum %1$s diese Daten benötigt.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blockieren</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Weitere Informationen</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-dsb/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-dsb/strings.xml
new file mode 100644
index 0000000000..c1654b04b7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-dsb/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s dowóliś, powěźeńki słaś?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s dowóliś, wašu kameru wužywaś?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s dowóliś, waš mikrofon wužywaś?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s dowóliś, wašo stojnišćo wužywaś?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s dowóliś, wašu kameru a waš mikrofon wužywaś?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Slězna kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Prědna kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Dowóliś</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Njedowóliś</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Rozsud za toś to sedło se spomnjeś</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Pśecej</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nigda</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Cośo %1$s dowóliś, daty w trajnem składowaku składowaś?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s dowóliś, aby wopśimjeśe wótgrał, kótaryž se pśez DRM wóźi?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s dowóliś, jogo cookieje na %2$s wužywaś?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Móžośo pśistup blokěrowaś, jolic njejo jasnje, cogodla %s toś te daty trjeba.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokěrowaś</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Dalšne informacije</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-el/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-el/strings.xml
new file mode 100644
index 0000000000..42d9abede5
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-el/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Να επιτρέπεται στο %1$s η αποστολή ειδοποιήσεων;</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Να επιτρέπεται στο %1$s η χρήση της κάμεράς σας;</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Να επιτρέπεται στο %1$s η χρήση του μικροφώνου σας;</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Να επιτρέπεται στο %1$s η χρήση της τοποθεσίας σας;</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Να επιτρέπεται στο %1$s η χρήση της κάμερας και του μικροφώνου σας;</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Μικρόφωνο 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Πίσω κάμερα</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Μπροστινή κάμερα</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Αποδοχή</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Απόρριψη</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Αποθήκευση απόφασης για τον ιστότοπο</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Πάντα</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Ποτέ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Να επιτρέπεται στο %1$s η αποθήκευση δεδομένων σε μόνιμη αποθήκευση;</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Να επιτρέπεται στο %1$s η αναπαραγωγή περιεχομένου με έλεγχο DRM;</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Να επιτρέπεται στο %1$s να χρησιμοποιεί τα cookie του στο %2$s;</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Ίσως θελήσετε να αποκλείσετε την πρόσβαση εάν δεν είναι σαφές το γιατί το %s χρειάζεται αυτά τα δεδομένα.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Φραγή</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Μάθετε περισσότερα</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rCA/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000000..9d9ff2ee68
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rCA/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Allow %1$s to send notifications?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Allow %1$s to use your camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Allow %1$s to use your microphone?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Allow %1$s to use your location?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Allow %1$s to use your camera and microphone?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microphone 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Rear-facing camera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Front-facing camera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Allow</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Don’t allow</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Remember decision for this site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Always</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Never</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Allow %1$s to store data in persistent storage?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Allow %1$s to play DRM-controlled content?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Allow %1$s to use its cookies on %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">You may want to block access if it\'s not clear why %s needs this data.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Block</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Learn more</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rGB/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000000..9d9ff2ee68
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-en-rGB/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Allow %1$s to send notifications?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Allow %1$s to use your camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Allow %1$s to use your microphone?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Allow %1$s to use your location?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Allow %1$s to use your camera and microphone?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microphone 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Rear-facing camera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Front-facing camera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Allow</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Don’t allow</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Remember decision for this site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Always</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Never</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Allow %1$s to store data in persistent storage?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Allow %1$s to play DRM-controlled content?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Allow %1$s to use its cookies on %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">You may want to block access if it\'s not clear why %s needs this data.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Block</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Learn more</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eo/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eo/strings.xml
new file mode 100644
index 0000000000..0504bef917
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eo/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Ĉu permesi al %1$s sendi sciigojn?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Ĉu permesi al %1$s uzi vian filmilon?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Ĉu permesi al %1$s uzi vian mikrofonon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Ĉu permesi al %1$s uzi vian pozicion?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Ĉu permesi al %1$s uzi vian filmilon kaj mikrofonon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Dorsa fimilo</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Fronta filmilo</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permesi</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ne permesi</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Memori decidon por tiu ĉi retejo</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Ĉiam</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Neniam</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Ĉu permesi al %1$s konservi datumojn en konstanta konservejo?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Ĉu permesi al %1$s ludi enhavon protektitan de DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Ĉu permesi al %1$s uzi siajn kuketojn en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Vi povus voli bloki la aliron, se ne estas klare, kial %s bezonas tiujn ĉi datumojn.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloki</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Pli da informo</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rAR/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rAR/strings.xml
new file mode 100644
index 0000000000..7ffaadd7ca
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rAR/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">¿Permitir que %1$s envíe notificaciones?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">¿Permitir que %1$s use la cámara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">¿Permitir que %1$s use el micrófono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">¿Permitir que %1$s use tu ubicación?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">¿Permitir que %1$s use la cámara y el micrófono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrófono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cámara trasera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cámara frontal</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recordar para este sitio</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Siempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿Permitir que %1$s guarde datos en el almacenamiento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿Permitir que %1$s reproduzca contenido controlado por DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿Permitir que %1$s use sus cookies en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Podés querer bloquear el acceso si no está claro por qué %s necesita estos datos.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Conocer más</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rCL/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rCL/strings.xml
new file mode 100644
index 0000000000..07ed53b907
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rCL/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">¿Permitir a %1$s enviar notificaciones?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">¿Permitir a %1$s usar tu cámara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">¿Permitir a %1$s usar tu micrófono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">¿Permitir a %1$s usar tu ubicación?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">¿Permitir a %1$s usar tu cámara y micrófono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrófono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cámara trasera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cámara delantera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recordar decisión para este sitio</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Siempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿Permitir a %1$s almacenar datos en el almacenamiento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿Permitir a %1$s reproducir contenido controlado por DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿Permitir que %1$s use sus cookies en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Puede que quieras bloquear el acceso si no está claro por qué %s necesita estos datos.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Aprender más</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rES/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rES/strings.xml
new file mode 100644
index 0000000000..b23c8a4bb6
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rES/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">¿Permitir que %1$s te envíe notificaciones?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">¿Permitir que %1$s use tu cámara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">¿Permitir que %1$s use tu micrófono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">¿Permitir que %1$s acceda a tu ubicación?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">¿Permitir que %1$s use tu cámara y micrófono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrófono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cámara trasera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cámara delantera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recordar para este sitio</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Siempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿Permitir a %1$s almacenar datos en el almacenamiento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿Permitir a %1$s reproducir contenido controlado por DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿Quieres permitir que %1$s utilice sus cookies en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Puede que quieras bloquear el acceso si no está claro por qué %s necesita estos datos.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saber más</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rMX/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rMX/strings.xml
new file mode 100644
index 0000000000..93a023dcbf
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es-rMX/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">¿Permitir que %1$s envíe notificaciones?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">¿Permitir que %1$s use tu cámara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">¿Permitir que %1$s use tu micrófono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">¿Permitir que %1$s use tu ubicación?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">¿Permitir que %1$s use tu cámara y micrófono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrófono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cámara trasera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cámara delantera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recordar decisión para este sitio</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Siempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿Permitir que %1$s almacene datos en el almacenamiento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿Permitir que %1$s reproduzca contenido controlado por DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿Permitir que %1$s use sus cookies en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Puede que quieras bloquear el acceso si no está claro por que %s necesita estos datos.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saber más</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000000..b23c8a4bb6
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-es/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">¿Permitir que %1$s te envíe notificaciones?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">¿Permitir que %1$s use tu cámara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">¿Permitir que %1$s use tu micrófono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">¿Permitir que %1$s acceda a tu ubicación?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">¿Permitir que %1$s use tu cámara y micrófono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrófono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cámara trasera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cámara delantera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Recordar para este sitio</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Siempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿Permitir a %1$s almacenar datos en el almacenamiento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿Permitir a %1$s reproducir contenido controlado por DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿Quieres permitir que %1$s utilice sus cookies en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Puede que quieras bloquear el acceso si no está claro por qué %s necesita estos datos.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saber más</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-et/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-et/strings.xml
new file mode 100644
index 0000000000..854bb486a3
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-et/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Kas lubad saidil %1$s saata teavitusi?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Kas lubad saidil %1$s kasutada oma kaamerat?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Kas lubad saidil %1$s kasutada oma mikrofoni?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Kas lubad saidil %1$s kasutada sinu asukoha teavet?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Kas lubad saidil %1$s kasutada oma kaamerat ja mikrofoni?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">tagumine kaamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">eesmine kaamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Luba</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ära luba</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Peetakse selle saidi jaoks meeles</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Alati</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mitte kunagi</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Kas lubada saidil %1$s salvestada andmeid püsivalt?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Kas lubada saidil %1$s esitada DRMiga kaitstud sisu?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Kas lubad saidil %1$s kasutada oma küpsiseid saidil %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Võid selle ligipääsu blokkida, kui pole selge, miks sait %s neid andmeid vajab.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloki</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Rohkem teavet</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eu/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eu/strings.xml
new file mode 100644
index 0000000000..8ce26c1175
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-eu/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Baimendu %1$s(r)i jakinarazpenak bidaltzea?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Baimendu %1$s(r)i zure kamera erabiltzea?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Baimendu %1$s(r)i zure mikrofonoa erabiltzea?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Baimendu %1$s(r)i zure kokapena erabiltzea?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Baimendu %1$s(r)i zure kamera eta mikrofonoa erabiltzea?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">1 Mikrofonoa</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Atzealdeko kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Aurreko kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Baimendu</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ez baimendu</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Gogoratu erabakia gune honetarako</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Beti</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Inoiz ez</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Baimendu %1$s guneari datuak biltegiratze iraunkorrean gordetzea?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Baimendu %1$s helbideari DRM bidez kontrolatutako edukia erreproduzitzen?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Baimendu %1$s guneari bere cookieak %2$s gunean erabiltzea?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Sarbidea blokeatu nahiko duzu ez badago garbi zergatik behar dituen datu hauek %s guneak.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokeatu</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Argibide gehiago</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fa/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fa/strings.xml
new file mode 100644
index 0000000000..fa3cac3003
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fa/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">به %1$s اجازه می‌دهید آگاهی بفرستد؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">به %1$s اجازه می‌دهید از دوربین شما استفاده کند؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">آیا %1$s اجازهٔ استفاده از صدابَر شما را دارد؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">به %1$s اجازه می‌دهید از مکان شما استفاده کند؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">آیا %1$s اجازهٔ استفاده از دوربین و صدابَر شما را دارد؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">صدابَر 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">دوربین عقب</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">دوربین جلو</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">اجازه دادن</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">اجازه ندادن</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">تصمیم را برای این پایگاه به خاطر بسپار</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">همیشه</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">هرگز</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">به %1$s اجازه‌ می‌دهید داده‌ها را در ذخیره‌گاه دائمی ذخیره کند؟</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">به %1$s اجازه می‌دهید محتوای واپایش شده با DRM را پخش کند؟</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">به %1$s اجازهٔ استفاده از کلوچک‌های خود در %2$s را می‌دهید؟</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">اگر مشخص نیست چرا %s به این داده‌ها نیاز دارد، ممکن است بخواهید دسترسی‌اش را مسدود کنید.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">مسدود کردن</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">بیشتر بدانید</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ff/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ff/strings.xml
new file mode 100644
index 0000000000..5929ed5628
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ff/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Yamir %1$s yo neldu tintine?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Yamir %1$s yo huutoro kameraa maa?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Yamir %1$s yo huutoro mikkoroo maa?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Yamir %1$s yo huutoro nokku maa?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Yamir %1$s yo huutoro kameraa maa e mikkoroo maa?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikkoroo1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kameraa caggal</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kameraa yeeso</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Yamir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Hoto Yamir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Siftor ɗuum e ndee lowre</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Ddaañaa</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Abadan</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Ɓeydu humpito</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fi/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fi/strings.xml
new file mode 100644
index 0000000000..4e494ce63c
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fi/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Sallitko, että %1$s lähettää ilmoituksia?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Sallitko, että %1$s käyttää kameraa?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Sallitko, että %1$s käyttää mikrofonia?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Sallitko, että %1$s käyttää sijaintia?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Sallitko, että %1$s käyttää kameraa ja mikrofonia?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofoni 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Takakamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Etukamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Salli</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Älä salli</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Muista valinta tälle sivustolle</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Aina</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">En koskaan</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Sallitko, että %1$s tallettaa tietoja pysyvään tallennustilaan?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Sallitko, että %1$s toistaa DRM-suojattua sisältöä?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Saako sivusto %1$s käyttää evästeitään sivustolla %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Haluat ehkä estää käytön, jos ei ole selvää, miksi %s tarvitsee nämä tiedot.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Estä</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Lue lisää</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fr/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000000..bbdde61732
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fr/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Autoriser %1$s à envoyer des notifications ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Autoriser %1$s à utiliser votre appareil photo ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Autoriser %1$s à utiliser votre microphone ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Autoriser %1$s à accéder à votre localisation ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Autoriser %1$s à utiliser votre appareil photo et votre microphone ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microphone 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Appareil photo arrière</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Appareil photo avant</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Autoriser</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ne pas autoriser</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Se souvenir de ce choix pour ce site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Toujours</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Jamais</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Autoriser %1$s à conserver des données dans le stockage persistant ?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Autoriser %1$s à lire du contenu contrôlé par DRM ?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Autoriser %1$s à utiliser ses cookies sur %2$s ?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Vous voudrez peut-être bloquer l’accès si vous ne savez pas exactement pourquoi %s a besoin de ces données.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquer</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">En savoir plus</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fur/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fur/strings.xml
new file mode 100644
index 0000000000..b813fd922d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fur/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permeti a %1$s di inviâ notifichis?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permeti a %1$s di doprâ la fotocjamare?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permeti a %1$s di doprâ il to microfon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permeti a %1$s di doprâ la tô posizion?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permeti a %1$s di doprâ la fotocjamare e il microfon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Fotocjamare posteriôr</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Fotocjamare frontâl</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permet</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No sta permeti</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Visiti de decision par chest sît</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Simpri</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Permeti a %1$s di archiviâ dâts te memorie persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permeti a %1$s di riprodusi contignûts controlâts di DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permeti a %1$s di doprâ i siei cookies su %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Si consee di blocâ l’acès se nol è clâr il motîf che al puarte %s a vê bisugne di chescj dâts.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloche</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Plui informazions</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fy-rNL/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fy-rNL/strings.xml
new file mode 100644
index 0000000000..bdf99aba53
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-fy-rNL/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s tastean om meldingen te ferstjoeren?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s tastean om jo kamera te brûken?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s tastean om jo mikrofoan te brûken?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s tastean om jo lokaasje te brûken?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s tastean om jo kamera en mikrofoan te brûken?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofoan 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kamera oan efterkant</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kamera oan foarkant</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Tastean</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Net tastean</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Beslissing ûnthâlde foar dizze website</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Altyd</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nea</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Bewarjen fan gegevens yn permaninte opslach troch %1$s tastean?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s tastean om DRM-kontrolearre ynhâld ôf te spyljen?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s tastean harren cookies te brûken op %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Jo kinne de tagong blokkearje as it net dúdlik is wêrom %s dizze gegevens nedich hat.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokkearje</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Mear ynfo</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ga-rIE/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ga-rIE/strings.xml
new file mode 100644
index 0000000000..c4ae48aba9
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ga-rIE/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Tabhair cead do %1$s fógraí a sheoladh?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Tabhair cead do %1$s an ceamara a úsáid?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Tabhair cead do %1$s an micreafón a úsáid?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Tabhair cead do %1$s do shuíomh a fheiceáil?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Tabhair cead do %1$s an ceamara agus an micreafón a úsáid?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micreafón 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Ceamara cúil</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Ceamara tosaigh</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Ceadaigh</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ná ceadaigh</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Meabhraigh an cinneadh don suíomh seo</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">I gcónaí</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Ná meabhraigh riamh</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gd/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gd/strings.xml
new file mode 100644
index 0000000000..5dd5cc7805
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gd/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">A bheil thu airson cead a thoirt dha %1$s brathan a chur?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">A bheil thu airson cead a thoirt dha %1$s an camara agad a chleachdadh?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">A bheil thu airson cead a thoirt dha %1$s am micreofon agad a chleachdadh?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">A bheil thu airson cothrom air d’ ionad a thoirt dha %1$s?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">A bheil thu airson cead a thoirt dha %1$s an camara ’s am micreofon agad a chleachdadh?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micreofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">An camara cùil</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">An camara beòil</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Ceadaich</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Na ceadaich</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Cuimhnich mo cho-dhùnadh airson na làraich seo</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">An-còmhnaidh</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Chan ann idir</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">An doir thu cead dha %1$s dàta a chumail san stòras bhuan?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">A bheil thu airson cead a thoirt dha %1$s susbaint fo smachd DRM a chluich?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">A bheil thu airson leigeil le %1$s na briosgaidean aice a chleachadh air %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Dh’fhaoidte gum b’ fheàirrde dhut an t-inntrigeadh a bhacadh mur eil thu cinnteach carson a dh’fheumas %s an dàta seo.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bac</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Barrachd fiosrachaidh</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gl/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gl/strings.xml
new file mode 100644
index 0000000000..9daf16fa99
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gl/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permitir que %1$s envíe notificacións?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permitir que %1$s empregue a súa cámara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permitir que %1$s empregue o seu micrófono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permitir que %1$s empregue a súa posición?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permitir que %1$s empregue a súa cámara e o seu micrófono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrófono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cámara posterior</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cámara frontal</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Non permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Lembrar decisión para este sitio</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Sempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Permitir que %1$s almacene datos en almacenamento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permitir que %1$s reproduza contido controlado por DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permitir que %1$s use as súas cookies en %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Será mellor que bloque o acceso se non ten claro para que necesita %s os seus datos.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Máis información</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gn/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gn/strings.xml
new file mode 100644
index 0000000000..bbe85a8a60
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gn/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Emoneĩpa %1$s omondóvo marandu’i?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Emoneĩpa %1$s oiporúvo ta’ãnganohẽha?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Emoneĩpa %1$s oiporúvo ñe’ẽatãha?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Emoneĩpa %1$s oikévo nerendaitépe?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Emoneĩpa %1$s oiporúvo ta’ãnganohẽha ha ñe’ẽatãha?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Ñe’ẽatãha 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Ta’ãnganohẽha kupegua</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Ta’ãnganohẽha tenondegua</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Moneĩ</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ani emoneĩ</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Eñemomandu’a je’ete ko tendápe g̃uarã</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Tapiaite</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Araka’eve</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">¿Emoneĩ %1$s ombyatývo mba’ekuaarã mbyatyrenda hi’arévape?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">¿Emoneĩ %1$s-pe ombohetávo tetepy DRM ohechapyre?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">¿Emoneĩse %1$s oiporúvo ikookie %2$s-pe?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Ikatu rejokose jeike nahesakãirõ mba’ére %s oikotevẽ ko’ã mba’ekuaarã.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Joko</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Kuaave</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gu-rIN/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000000..e527d320ac
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-gu-rIN/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$sને સૂચનાઓ મોકલવાની મંજૂરી આપીએ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$sને તમારા કેમેરાનો ઉપયોગ કરવાની મંજૂરી આપીએ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$sને તમારા માઇક્રોફોનનો ઉપયોગ કરવાની મંજૂરી આપીએ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$sને તમારું સ્થાન વાપરવાની મંજૂરી આપીએ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$sને તમારા કેમેરા અને માઇક્રોફોનનો ઉપયોગ કરવાની મંજૂરી આપીએ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">માઇક્રોફોન 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">રીઅર-ફેસિંગ કેમેરો</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ફ્રન્ટ-ફેસિંગ કેમેરો</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">પરવાનગી આપો</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">મંજૂરી આપશો નહીં</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">આ સાઇટ માટે નિર્ણય યાદ રાખો</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">હંમેશા</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ક્યારેય નહિં</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hi-rIN/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hi-rIN/strings.xml
new file mode 100644
index 0000000000..c8e4900565
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hi-rIN/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s को सूचनाएँ भेजने की अनुमति दें?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s को अपने कैमरे का उपयोग करने की अनुमति दें?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s को अपने माइक्रोफोन के उपयोग की अनुमति दें?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s को अपने स्थान के उपयोग की जानकारी दें?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s को अपने कैमरे और माइक्रोफोन के उपयोग की अनुमति दें?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">माइक्रोफोन 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">पीछे का कैमरा</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">आगे का कैमरा</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">अनुमति दें</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">अनुमति न दें</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">इस साइट के लिए निर्णय याद रखें</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">हमेशा</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">कभी नहीं</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hil/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hil/strings.xml
new file mode 100644
index 0000000000..e44b8bf943
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hil/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Pahanugtan</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hr/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hr/strings.xml
new file mode 100644
index 0000000000..fd3321a064
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hr/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Dozvoliti da %1$s šalje obavijesti?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Dozvoliti da %1$s koristi tvoju kameru?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Dozvoliti da %1$s koristi tvoj mikrofon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Dozvoliti da %1$s koristi tvoju lokaciju?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Dozvoliti da %1$s koristi tvoju kameru i mikrofon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Stražnja kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Prednja kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Dozvoli</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Nemoj dozvoliti</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Zapamti odluku za ovu stranicu</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Uvijek</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nikada</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Dopustiti stranici %1$s spremanje podataka u trajnu pohranu?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Dopustiti stranici %1$s reprodukciju sadržaja kontroliranog DRM-om?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Dopusti %1$s da koristi svoje kolačiće na %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Vjerojatno ćete htjeti blokirati pristup ukoliko nije jasno zašto %s treba ove podatke.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokiraj</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saznajte više</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hsb/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hsb/strings.xml
new file mode 100644
index 0000000000..240b3f439c
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hsb/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s dowolić, zdźělenki słać?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s dowolić, wašu kameru wužiwać?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s dowolić, waš mikrofon wužiwać?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s dowolić, waše stejnišćo wužiwać?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s dowolić, wašu kameru a waš mikrofon wužiwać?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Zadnja kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Prědnja kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Dowolić</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Njedowolić</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Rozsud za tute sydło sej spomjatkować</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Přeco</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Ženje</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Smě %1$s daty w trajnym składowaku składować?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s dowolić, zo byšće wobsah wothrał, kotryž so přez DRM wodźi?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s dowolić, jeho placki na %2$s wužiwać?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Móžeće přistup blokować, jeli jasnje njeje, čehodla %s tute daty trjeba.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokować</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Dalše informacije</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hu/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hu/strings.xml
new file mode 100644
index 0000000000..11021d9a92
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hu/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Engedélyezi, hogy a(z) %1$s értesítéseket küldjön?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Engedélyezi, hogy a(z) %1$s használja a kameráját?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Engedélyezi, hogy a(z) %1$s használja a mikrofonját?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Engedélyezi, hogy a(z) %1$s elérje a tartózkodási helyét?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Engedélyezi, hogy a(z) %1$s használja a kameráját és mikrofonját?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">1. mikrofon</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Hátlapi kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Előlapi kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Engedélyezés</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Tiltás</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Döntés megjegyzése ehhez az oldalhoz</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Mindig</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Soha</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Engedélyezi, hogy a(z) %1$s adatokat tároljon az állandó tárolóban?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Engedélyezi, hogy a(z) %1$s DRM által vezérelt tartalmat játsszon le?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Engedélyezi, hogy a(z) %1$s használja a sütijeit a(z) %2$s webhelyen?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Érdemes lehet letiltani a hozzáférést, ha nem világos, hogy a(z) %s webhelynek miért van szüksége ezekre az adatokra.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Tiltás</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">További tudnivalók</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hy-rAM/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000000..fc0ec838d1
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-hy-rAM/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Թույլատրե՞լ %1$s-ին ծանուցումներ ուղարկել:</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Թույլատրե՞լ %1$s-ին օգտագործել Ձեր տեսախցիկը:</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Թույլատրե՞լ %1$s-ին օգտագործել ձեր խոսափողը:</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Թույլատրե՞լ %1$s-ին օգտագործել ձեր տեղադրությունը:</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Թույլատրե՞լ %1$s-ին օգտագործել Ձեր տեսախցիկը և խոսափողը:</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Խոսափող 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Ետին տեսախցիկ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Դիմային տեսախցիկ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Թույլատրել</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Չթույլատրել</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Հիշել այս կայքի որոշումը</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Միշտ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Երբեք</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Թույլատրե՞լ %1$s-ին պահել տվյալներ մշտական պահեստում:</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Թույլատրե՞լ %1$s-ին նվագարկել DRM ղեկավարվող բովանդակություն:</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Թույլատրե՞լ %1$s-ին օգտագործել իր թխուկները %2$s-ում:</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Դուք կարող եք արգելափակել մատչումը, եթե պարզ չէ, թե ինչու են %s-ին անհրաժեշտ այս տվյալները:</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Արգելափակել</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Իմանալ ավելին</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ia/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ia/strings.xml
new file mode 100644
index 0000000000..eff151bc66
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ia/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permitte tu que %1$s invia notificationes?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permitte tu que %1$s usa tu camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permitte tu que %1$s usa tu microphono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permitte tu que %1$s usa tu ubication?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permitte tu que %1$s usa tu camera e tu microphono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microphono1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Camera dorsal</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Camera frontal</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitter</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Non permitter</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Rememorar le decision pro iste sito</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Sempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunquam</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Permitte tu que %1$s stocka datos in le memoria persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permitte tu a %1$s de reproducer le contento protegite per DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permitter que %1$s usa su cookies sur %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Es un bon idea blocar le accesso si non es clar proque %s require iste datos.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blocar</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Pro saper plus</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-in/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-in/strings.xml
new file mode 100644
index 0000000000..f365049aa7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-in/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Izinkan %1$s untuk mengirim pemberitahuan?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Izinkan %1$s untuk menggunakan kamera Anda?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Izinkan %1$s untuk menggunakan mikrofon Anda?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Izinkan %1$s menggunakan lokasi Anda?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Izinkan %1$s menggunakan kamera dan mikrofon Anda?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kamera hadap belakang</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kamera hadap depan</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Izinkan</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Jangan izinkan</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Ingat pilihan pada situs ini</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Selalu</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Tidak Pernah</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Izinkan %1$s untuk menyimpan data di penyimpanan persisten?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Izinkan %1$s untuk memutar konten yang dikendalikan DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Izinkan %1$s untuk menggunakan kuki-nya di %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Anda mungkin ingin memblokir akses jika alasan %s membutuhkan data ini tidak jelas.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokir</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Pelajari lebih lanjut</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-is/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-is/strings.xml
new file mode 100644
index 0000000000..97849f46b6
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-is/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Leyfa %1$s að senda tilkynningar?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Leyfa %1$s að nota myndavélina þína?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Leyfa %1$s að nota hljóðnemann þinn?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Leyfa %1$s að nota staðsetninguna þína?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Leyfa %1$s að nota myndvélina þína og hljóðnema?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Hljóðnemi 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Bak myndavélin</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Fram myndavélin</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Leyfa</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ekki leyfa</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Mundu ákvörðun fyrir þetta vefsvæði</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Alltaf</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Aldrei</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Leyfa %1$s að geyma gögn í varanlegri geymslu?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Leyfa %1$s að spila DRM-stýrt efni?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Leyfa %1$s að nota vefkökur sínar á %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Þú gætir viljað loka fyrir aðgang ef það er ekki ljóst hvers vegna %s þarfnast þessara gagna.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Loka á</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Frekari upplýsingar</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-it/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-it/strings.xml
new file mode 100644
index 0000000000..96d1bbe036
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-it/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Consentire a %1$s di inviare notifiche?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Consentire a %1$s di utilizzare la fotocamera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Consentire a %1$s di utilizzare il microfono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Consentire a %1$s di utilizzare la posizione?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Consentire a %1$s di utilizzare la fotocamera e il microfono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Fotocamera posteriore</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Fotocamera frontale</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Consenti</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Non permettere</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Ricorda la scelta per questo sito</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Sempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Consentire a %1$s di salvare i dati nella memoria permanente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Consentire a %1$s di riprodurre contenuti protetti da DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Consentire a %1$s di utilizzare i propri cookie su %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">È consigliabile bloccare l’accesso se non è chiaro per quale motivo %s abbia bisogno di questi dati.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blocca</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Ulteriori informazioni</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-iw/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-iw/strings.xml
new file mode 100644
index 0000000000..250fcbd7a9
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-iw/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">האם לאפשר ל־%1$s לשלוח התרעות?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">האם לאפשר ל־%1$s להשתמש במצלמה שלך?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">האם לאפשר ל־%1$s להשתמש במיקרופון שלך?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">האם לאפשר ל־%1$s להשתמש במיקום שלך?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">האם לאפשר ל־%1$s להשתמש במצלמה ובמיקרופון שלך?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">מיקרופון 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">מצלמה אחורית</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">מצלמה קדמית</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">לאפשר</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">לא לאפשר</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">שמירת הבחירה עבור אתר זה</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">תמיד</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">לעולם לא</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">האם לאפשר ל־%1$s לשמור מידע באחסון הקבוע?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">האם לאפשר ל־%1$s לנגן תוכן מוגן DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">לאפשר ל־%1$s להשתמש בעוגיות שלו ב־%2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">אם לא ברור לך מדוע %s זקוק לנתונים האלו, ייתכן שכדאי לחסום את הגישה.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">חסימה</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">מידע נוסף</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ja/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ja/strings.xml
new file mode 100644
index 0000000000..c485853162
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ja/strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s に通知の送信を許可しますか?</string>
+
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s にカメラの使用を許可しますか?</string>
+
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s にマイクの使用を許可しますか?</string>
+
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s に位置情報の使用を許可しますか?</string>
+
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s にカメラとマイクの使用を許可しますか?</string>
+
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">マイク 1</string>
+
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">背面カメラ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">前面カメラ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">許可する</string>
+
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">許可しない</string>
+
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">今後も同様に処理する</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">常に許可</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">常に不許可</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s に永続ストレージへのデータの格納を許可しますか?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s に DRM 制御されたコンテンツの再生を許可しますか?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%2$s で Cookie の利用を %1$s に許可しますか?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s がこのデータを利用する理由が不明な場合は、アクセスのブロックをおすすめします。</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">ブロック</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">詳細情報</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ka/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ka/strings.xml
new file mode 100644
index 0000000000..d198f64a48
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ka/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">ნებას რთავთ %1$s-ს გაჩვენოთ შეტყობინებები?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">ნებას რთავთ %1$s-ს, გამოიყენოს კამერა?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">ნებას რთავთ %1$s-ს, გამოიყენოს მიკროფონი?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">ნებას რთავთ %1$s-ს, გამოიყენოს თქვენი მდებარეობა?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">ნებას რთავთ %1$s-ს, გამოიყენოს კამერა და მიკროფონი?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">მიკროფონი 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">უკანა ხედვის კამერა</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">წინა ხედვის კამერა</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">დაშვება</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">აკრძალვა</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">დამახსოვრება ამ საიტისთვის</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ყოველთვის</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">არასდროს</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">ნებას რთავთ %1$s-ს, შეინახოს მონაცემები მუდმივ მეხსიერებაზე?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">გსურთ, %1$s-მ გაუშვას DRM-დაქვემდებარებული შიგთავსი?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">ნებას რთავთ %1$s-ს, გამოიყენოს ფუნთუშები %2$s-ზე?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">უმჯობესია აკრძალოთ წვდომა, თუ ნათელი არაა, რისთვის საჭიროებს %s ამ მონაცემებს.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">აკრძალვა</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ვრცლად</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kaa/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kaa/strings.xml
new file mode 100644
index 0000000000..bf3121685a
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kaa/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s ushın xabarlamalardı jiberiwdi ruqsat etiw kerek pe?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s ushın kamerańızdan qollanıwdı ruqsat etiw kerek pe?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s ushın mikrofonıńızdan paydalanıwdı ruqsat etiw kerek pe?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s ushın jaylasqan ornıńızdı paydalanıwǵa ruqsat etiw kerek pe?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s ushın kamera hám mikrofonıńızdı paydalanıwǵa ruqsat etiw kerek pe?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Artqı kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Aldınǵı kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Ruqsat beriw</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ruqsat etpew</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Bul sayt ushın qarardı este saqlaw</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Hámiyshe</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Heshqashan</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s ushın maǵlıwmatlardı turaqlı saqlaw ornında saqlawǵa ruqsat etiw kerek pe?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s ushın avtor huqıqları menen qorǵalǵan kontentti qoyıwdı ruqsat etiw kerek pe?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s ǵa %2$s daǵi cookielerdi paydalanıwǵa ruqsat etilsin be?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Eger siz %s saytına bul maǵlıwmatlar nege kerek ekenligin túsinbeseńiz, kiriwdi bloklawıńız múmkin.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloklaw</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Tolıǵıraq úyreniw</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kab/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kab/strings.xml
new file mode 100644
index 0000000000..0e0d63ad13
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kab/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Sireg %1$s ad yazen tilɣa?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Sireg %1$s ad isegdec takamiṛat?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Sireg %1$s ad isegdec aṣawaḍ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Sireg %1$s ad iseqdec adig-ik?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Sireg %1$s ad iseqdec takamiṛat-ik akked usawaḍ-ik?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Asawaḍ 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Ibenk n tkamiṛat n deffir</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Takamirat n sdat</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Sireg</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ur sirig ara</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Cfu ɣef ufran-iw i usmel-a</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Yal tikkelt</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Werǧin</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Ad teǧǧeḍ %1$s ad issekles isefka deg uselkim-ik•im?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Sireg %1$s ad d-iɣer agbur yettwasneqden sɣur DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Sireg %1$s ad isseqdec inagan-is n tuqqna ɣef %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Ahat tebɣiḍ ad tesweḥleḍ anekcum ma yella ur d-iban ara ayɣer %s yesra isefka-a.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Sewḥel</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Issin ugar</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kk/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kk/strings.xml
new file mode 100644
index 0000000000..620a106672
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kk/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s үшін хабарламаларды жіберуді рұқсат ету керек пе?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s үшін камераңызды қолдану рұқсат ету керек пе?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s үшін микрофоныңызды қолдану рұқсат ету керек пе?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s үшін орналасуыңызды қолдану рұқсат ету керек пе?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s үшін камера және микрофоныңызды қолдануды рұқсат ету керек пе?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Микрофон 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Артқы камера</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Алдыңғы камера</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Рұқсат ету</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Рұқсат етпеу</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Бұл сайт үшін таңдауымды есте сақтау</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Әрқашан</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Ешқашан</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s үшін деректерді тұрақты қоймада сақтауды рұқсат ету керек пе?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s үшін DRM-мен басқарылатын құраманы ойнатуды рұқсат ету керек пе?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s үшін %2$s жеріндегі cookie файлдарын қолдануға рұқсат беру керек пе?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s бұл деректерге қатынау мақсаты түсініксіз болса, қатынау құқығын бұғаттауыңызға болады.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Блоктау</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Көбірек білу</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kmr/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kmr/strings.xml
new file mode 100644
index 0000000000..ab701f2540
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kmr/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s, bila danezanan bişîne?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s, bila kameraya te bi kar bîne?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s, bila mîkrofona te bi kar bîne?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s, bila cîgeha te bi kar bîne?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s, bila kamera û mîkrofona te bi kar bîne?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mîkrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kameraya paşiyê</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kameraya pêşiyê</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Destûrê bide</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Destûrê nede</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Biryara min ji bo vê malperê bi bîr bîne</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Timî</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Qet</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s, bila daneyan li bîrgeha mayinde hilîne?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s, bila naverokên bi DRM-kontrolkirî bilîzîne?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Destûrê bidî %1$s`ê ku çerezên xwe di %2$s`ê de bi kar bîne?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Heke ne zelal be ka çima pêdiviya %s`ê bi van agahiyan heye, tu dikarî gihîştinê asteng bikî.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Asteng bike</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Agahiyên zêdetir</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kn/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kn/strings.xml
new file mode 100644
index 0000000000..45f6aeef23
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-kn/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಳುಹಿಸಲು %1$s ಅನ್ನು ಅನುಮತಿಸುವುದೇ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">ನಿಮ್ಮ ಕ್ಯಾಮೆರಾ ಬಳಸಲು %1$s ಅನ್ನು ಅನುಮತಿಸುವುದೇ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">ನಿಮ್ಮ ಮೈಕ್ರೊಫೋನ್ ಬಳಸಲು %1$s ಅನ್ನು ಅನುಮತಿಸುವುದೇ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಬಳಸಲು %1$s ಅನ್ನು ಅನುಮತಿಸುವುದೇ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">ನಿಮ್ಮ ಕ್ಯಾಮೆರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್ ಬಳಸಲು %1$s ಅನ್ನು ಅನುಮತಿಸುವುದೇ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ಮೈಕ್ರೊಫೋನ್ 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">ಹಿಂಭಾಗದ ಕ್ಯಾಮೆರಾ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ಮುಮ್ಮುಖ ಕ್ಯಾಮೆರ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ಅನುಮತಿಸು</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ಅನುಮತಿಸ ಬೇಡ‍</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ಈ ಸೈಟ್‌ನ ನಿರ್ಧಾರವನ್ನು ನೆನಪಿಡಿ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ಯಾವಾಗಲೂ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ಎಂದಿಗೂ ಬೇಡ</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ko/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ko/strings.xml
new file mode 100644
index 0000000000..c2a607dd77
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ko/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s가 알림을 보내도록 허용하시겠습니까?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s가 카메라를 사용하도록 허용하시겠습니까?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s가 마이크를 사용하도록 허용하시겠습니까?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s가 사용자 위치를 사용하도록 허용하시겠습니까?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s가 카메라와 마이크를 사용하도록 허용하시겠습니까?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">마이크 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">후면 카메라</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">전면 카메라</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">허용</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">허용 안 함</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">이 사이트에 대한 결정을 기억하기</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">항상</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">안 함</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s 페이지가 데이터를 영구 저장소에 저장하도록 허용하시겠습니까?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s에서 DRM 제어 콘텐츠를 재생하도록 허용하시겠습니까?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s 사이트가 %2$s 사이트에서 쿠키를 사용하도록 허용하시겠습니까?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s에 이 데이터가 필요한 이유가 명확하지 않은 경우 액세스를 차단할 수 있습니다.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">차단</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">더 알아보기</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lij/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lij/strings.xml
new file mode 100644
index 0000000000..b166befcd9
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lij/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permette a %1$s de mandâ notifiche?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permette a %1$s de deuviâ a fòtocamera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permette a %1$s de deuviâ o micròfono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permette a %1$s de deuviâ a teu poxiçion?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permette a %1$s de deuviâ a fòtocamera e micròfono ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micròfono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Fòtocamera derê</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Fòtocamera davanti</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permetti</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No permette</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Aregòrda sta decixon pe sto scito</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">De longo</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lo/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lo/strings.xml
new file mode 100644
index 0000000000..a561eec25f
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lo/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">ອະນຸຍາດໃຫ້ %1$s ສົ່ງການແຈ້ງເຕືອນບໍ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">ອະນຸຍາດໃຫ້ %1$s ໃຊ້ກ້ອງຖ່າຍຮູບຂອງທ່ານບໍ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">ອະນຸຍາດໃຫ້ %1$s ໃຊ້ໄມໂຄຣໂຟນຂອງທ່ານບໍ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">ອະນຸຍາດໃຫ້ %1$s ໃຊ້ທີ່ຢູ່ຂອງທ່ານບໍ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">ອະນຸຍາດໃຫ້ %1$s ໃຊ້ກ້ອງຖ່າຍຮູບ ແລະ ໄມໂຄຣໂຟນຂອງທ່ານບໍ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ໄມໂຄຣໂຟນ 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">ກ້ອງຫລັງ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ກ້ອງຫນ້າ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ອະນຸຍາດ</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ບໍ່ອະນຸຍາດ</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ຈືຂໍ້ມູນການຕັດສິນໃຈສໍາລັບເວັບໄຊທນີ້</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ອະນຸຍາດຕະຫຼອດ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ບໍ່ອະນຸຍາດເລີຍ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">ອະນຸຍາດໃຫ້ %1$s ເກັບຂໍ້ມູນໄວ້ໃນສະຕໍເລຢ່າງຖາວອນ?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">ອະນຸຍາດໃຫ້ %1$s ເປີດເນື້ອຫາ DRM-controlled ບໍ?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">ອະນຸຍາດໃຫ້ %1$s ໃຊ້ຄຸກກີ້ຂອງມັນຢູ່ໃນ %2$s ຫລືບໍ?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">ທ່ານສາມາດບລັອກການເຂົ້າເຖິງໄດ້ຫາກວ່າທ່ານບໍ່ແນ່ໃຈໃນເຫດຜົນທີ່ %s ຕ້ອງການຂໍ້ມູນນີ້.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">ບລັອກ</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ຮຽນຮູ້ເພີ່ມເຕີມ</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lt/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lt/strings.xml
new file mode 100644
index 0000000000..ab5e195305
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-lt/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Leisti %1$s siųsti pranešimus?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Leisti %1$s naudoti jūsų kamerą?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Leisti %1$s naudoti jūsų mikrofoną?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Leisti %1$s nustatyti jūsų buvimo vietą?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Leisti %1$s naudoti jūsų kamerą ir mikrofoną?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofonas 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Galinė kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Priekinė kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Leisti</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Neleisti</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Įsiminti pasirinkimą šiai svetainei</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Visada</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Niekada</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Leisti %1$s laikyti duomenis išliekančioje atmintyje?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Liesti %1$s groti DRM apsaugotą turinį?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Leisti %1$s naudoti savo slapukus esant %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Galite neleisti, jei nėra aišku, kodėl %s reikia šių duomenų.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Neleisti</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Sužinoti daugiau</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ml/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ml/strings.xml
new file mode 100644
index 0000000000..511fda396d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ml/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">അറിയിപ്പുകൾ അയയ്ക്കാൻ %1$s നെ അനുവദിക്കണോ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">താങ്കളുTe ക്യാമറ ഉപയോഗിക്കാൻ %1$s നെ അനുവദിക്കണോ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">താങ്കളുടെ മൈക്രോഫോൺ ഉപയോഗിക്കാൻ %1$s നെ അനുവദിക്കണോ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">താങ്കളുടെ സ്ഥാനം ഉപയോഗിക്കാൻ %1$s നെ അനുവദിക്കണോ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">താങ്കളുTe ക്യാമറയും മൈക്രോഫോണും ഉപയോഗിക്കാൻ %1$s നെ അനുവദിക്കണോ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">മൈക്രോഫോൺ 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">പിൻവശത്തെ ക്യാമറ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">മുൻവശത്തെ ക്യാമറ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">അനുവദിക്കുക</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">അനുവദിക്കരുത്</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ഈ സൈറ്റിനായുള്ള തീരുമാനം ഓർമ്മിക്കുക</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">എപ്പോഴും</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ഒരിക്കലും അരുത്</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-mr/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-mr/strings.xml
new file mode 100644
index 0000000000..d61d2bff13
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-mr/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s ला सूचना पाठविण्यास परवानगी द्यायची?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s ला आपला कॅमेरा वापरण्याची परवानगी द्यायची?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s ला आपला मायक्रोफोन वापरण्याची परवानगी द्यायची?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s ला आपले स्थान वापरण्याची परवानगी द्यायची?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s ला आपला कॅमेरा आणि मायक्रोफोन वापरण्याची परवानगी द्यायची?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">मायक्रोफोन 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">मागचा कॅमेरा</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">समोरचा कॅमेरा</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">परवानगी द्या</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">परवानगी देऊ नका</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">या साइटसाठी निर्णय लक्षात ठेवा</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">नेहमी</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">कधीच नाही</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-my/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-my/strings.xml
new file mode 100644
index 0000000000..0e1f032e68
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-my/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s အား အသိပေးချက်များကို ပေးပို့ရန် ခွင့်ပြုပါ။</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">သင့်ကင်မရာ အသုံးပြုရန် %1$s ကို ခွင့်ပေးပါမည်လား။</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">သင့်မိုက်ကရိုဖုန်း အသုံးပြုရန် %1$s ကို ခွင့်ပေးပါမည်လား။</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">သင့်တည်နေရာကို %1$s သုံးရန်ခွင့်ပြုမလား။</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">သင့်ကင်မရာနှင့် မိုက်ကရိုဖုန်း အသုံးပြုရန် %1$s ကို ခွင့်ပေးပါမည်လား။</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">မိုက်ကရိုဖုန်း 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">နောက်ဘက်ကင်မရာ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">မျက်နှာဘက် ကင်မရာ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ခွင့်ပြုပါ</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ခွင့်မပြုပါနှင့်</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ဤဆိုဘ်အတွက် ဆုံးဖြတ်ချက်ကို မှတ်ထားပါ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">အမြဲတမ်း</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ဘယ်တော့မှ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">အမြဲမပြတ်သိုလှောင်မှုတွင် %1$s ကို အချက်အလက်သိမ်းဆည်းခွင့်ပြုမည်လား</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">DRM ထိန်းချုပ်ထားသော အကြောင်းအရာများကို %1$s အား ဆောင်ရွက် ခွင့်ပြုမည်လား။</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nb-rNO/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nb-rNO/strings.xml
new file mode 100644
index 0000000000..fb36bb863e
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nb-rNO/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Tillat %1$s å sende varsler?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Tillat %1$s å bruke kameraet?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Tillat %1$s å bruke mikrofonen?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Tillat %1$s å bruke posisjonen din?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Tillat %1$s å bruke kameraet og mikrofonen?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Bakovervendt kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Fremovervendt kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Tillat</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ikke tillat</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Husk avgjørelsen for dette nettstedet</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Alltid</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Aldri</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Tillate %1$s å lagre data i vedvarende lagring?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Tillate %1$s å spille av DRM-kontrollert innhold?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Vil du tillate %1$s å bruke sine infokapsler på %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Det kan være lurt å blokkere tilgang hvis det ikke er klart hvorfor %s trenger disse dataene.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokker</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Les mer</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ne-rNP/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000000..f7ea5c009f
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ne-rNP/strings.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s लाई सूचनाहरू पठाउन अनुमति दिन चाहानुहुन्छ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s लाई आफ्नो क्यामरा प्रयोग गर्न दिन चाहानुहुन्छ ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s लाई आफ्नो माइक्रोफोन प्रयोग गर्न दिन चाहानुहुन्छ ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s लाई आफ्नो स्थान प्रयोग गर्न दिन चाहानुहुन्छ ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s लाई आफ्नो क्यामरा र माइक्रोफोन प्रयोग गर्न दिन चाहानुहुन्छ ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">माइक्रोफोन 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">पछाडि फर्किएको क्यामरा</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">अगाडी फर्किएको क्यामरा</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">अनुमति दिनुहोस्</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">अनुमति नदिनुहोस्</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">यस साइटको लागि निर्णय सम्झनुहोस्</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">सधैँ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">कहिल्यै पनि होइन</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s लाई लगातार भण्डारणमा डेटा भण्डारण गर्न अनुमति दिन चाहानुहुन्छ?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">DRM-नियन्त्रित सामग्री बजाउन %1$s लाई अनुमति दिन चाहानुहुन्छ?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s लाई %2$s मा यसको कुकीहरू प्रयोग गर्न दिने हो?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s लाई यो डाटा किन चाहिन्छ भन्ने कुरा स्पष्ट नभएको खण्डमा तपाईले पहुँचलाई रोक लगाउन सक्नुहुन्छ।</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">अझ जान्नुहोस्</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nl/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nl/strings.xml
new file mode 100644
index 0000000000..5e9095c0cc
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nl/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s toestaan om meldingen te verzenden?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s toestaan om uw camera te gebruiken?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s toestaan om uw microfoon te gebruiken?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s toestaan om uw locatie te gebruiken?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s toestaan om uw camera en microfoon te gebruiken?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfoon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Camera aan achterzijde</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Camera aan voorzijde</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Toestaan</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Niet toestaan</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Beslissing onthouden voor deze website</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Altijd</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nooit</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Bewaren van gegevens in permanente opslag door %1$s toestaan?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s toestaan om DRM-gecontroleerde inhoud af te spelen?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s toestaan zijn cookies te gebruiken op %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">U kunt de toegang blokkeren als het niet duidelijk is waarom %s deze gegevens nodig heeft.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokkeren</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Meer info</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nn-rNO/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nn-rNO/strings.xml
new file mode 100644
index 0000000000..03df810bf0
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-nn-rNO/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Tillate %1$s å sende varsel?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Tillate %1$s å bruke kameraet?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Tillate %1$s å bruke mikrofonen?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Tillate %1$s å bruke plasseringa di?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Tillate %1$s å bruke kamera og mikrofon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Bakovervendt kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Framovervendt kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Tillat</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ikkje tillat</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Hugs avgjerda for denne sida</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Alltid</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Aldri</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Tillate %1$s å lagre data i vedvarande lagring?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Tillate %1$s å spele DRM-kontrollert innhald?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Tilate %1$s å bruke infokapslane sine på %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Det kan vere lurt å blokkere tilgang viss det ikkje er klart kvifor %s treng desse dataa.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blokker</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Les meir</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-oc/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-oc/strings.xml
new file mode 100644
index 0000000000..58d57d4cd7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-oc/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Autorizar %1$s a enviar de notificacions ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Autorizar %1$s a utilizar vòstra camèra ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Autorizar %1$s a utilizar vòstre microfòn ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Autorizar %1$s a utilizar vòstre emplaçament ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Autorizar %1$s a utilizar vòstra camèra e vòstre microfòn ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfòn 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Camèra rèire</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Camèra frontala</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Autorizar</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Autorizar pas</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Se remembrar d’aquesta causida per aqueste site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Totjorn</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Pas jamai</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Voletz autorizar %1$s a servar las donadas dins l’estocatge persistent ?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permetre a %1$s de legir lo contengut contrarotlat per DRM ?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permetre a %1$s d’utilizar sos cookies sus %2$s ?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Volriatz benlèu blocar l’accès se sabètz pas exactament perque %s a mestièr de vòstras donadas.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blocar</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Ne saber mai</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-or/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-or/strings.xml
new file mode 100644
index 0000000000..3805a262ac
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-or/strings.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ମାଇକ୍ରୋଫୋନ 1</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ସର୍ବଦା</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">କଦାପି ନୁହେଁ</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ଅଧିକ ଜାଣନ୍ତୁ</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rIN/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rIN/strings.xml
new file mode 100644
index 0000000000..e53aa49003
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rIN/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s ਨੂੰ ਸੂਚਨਾਵਾਂ ਦੇਣ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s ਨੂੰ ਆਪਣਾ ਕੈਮਰਾ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s ਨੂੰ ਆਪਣਾ ਮਾਈਕਰੋਫ਼ੋਨ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s ਨੂੰ ਆਪਣਾ ਟਿਕਾਣਾ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s ਨੂੰ ਆਪਣਾ ਕੈਮਰਾ ਅਤੇ ਮਾਈਕਰੋਫ਼ੋਨ ਵਰਤਣ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ਮਾਈਕਰੋਫ਼ੋਨ 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">ਪਿਛਲੇ ਪਾਸੇ ਵਾਲਾ ਕੈਮਰਾ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ਅੱਗੇ ਪਾਸੇ ਵਾਲਾ ਕੈਮਰਾ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ਆਗਿਆ ਦਿਓ</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ਆਗਿਆ ਨਾ ਦਿਓ</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ਇਸ ਸਾਈਟ ਲਈ ਫ਼ੈਸਲਾ ਯਾਦ ਰੱਖੋ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ਹਮੇਸ਼ਾਂ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ਕਦੇ ਨਹੀਂ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">ਕੀ %1$s ਨੂੰ ਪੱਕੀ ਸਟੋਰੇਜ਼ ਵਿੱਚ ਡਾਟਾ ਸਟੋਰ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">ਕੀ %1$s ਨੂੰ DRM-ਕੰਟਰੋਲ ਕੀਤੀ ਸਮੱਗਰੀ ਚਲਾਉਣ ਦੀ ਮਨਜ਼ੂਰੀ ਦੇਣੀ ਹੈ?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s ਨੂੰ %2$s ਉੱਤੇ ਆਪਣੇ ਕੂਕੀਜ਼ ਵਰਤਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">ਜੇ ਤੁਹਾਨੂੰ ਭਰੋਸਾ ਨਹੀਂ ਹੈ ਕਿ %s ਨੂੰ ਇਹ ਡਾਟਾ ਕਿਓ ਚਾਹੀਦਾ ਹੈ ਤਾਂ ਤੁਸੀਂ ਇਹ ਪਹੁੰਚ ਤੇ ਰੋਕ ਲਾ ਸਕਦੇ ਹੋ।</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">ਪਾਬੰਦੀ</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ਹੋਰ ਸਿੱਖੋ</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rPK/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rPK/strings.xml
new file mode 100644
index 0000000000..3d4a2e517c
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pa-rPK/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s نوں نوٹ دیوݨ دی اجازت دیو؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s نوں کیمرے ورتݨ دی اجازت دیو؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s نوں مائیکروفون ورتݨ دی اجازت دیو؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s نوں مقام ورتݨ دی اجازت دیو؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s نوں کیمرے تے مائیکروفون ورتݨ دی اجازت دیو؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">مائیکروفون 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">پچھلے پاسے والا کیمرا</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">اگے پاسے والا کیمرا</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">اجازت دیو</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">اجازت نہ دیو</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ایس سائٹ لئی فیصلہ یاد رکھو</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ہمیشہ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">کدے نہیں</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s نوں فون وچ ڈیٹے رکھݨ دی اجازت دیو؟</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s نوں کاپی منع دیاں فائلاں ورتݨ دی اجازت دیو؟</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s نوں %2$s تے کوکی ورتݨ دی اجازت دیو؟</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">جے تہانوں بھروسہ نہیں اے کہ %s نوں ایہہ ڈیٹا کیوں چاہیدا اے تاں تسیں ایہہ پہنچ تے روک لا سکدے او۔</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">اجازت نہ دیو</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ہور جاݨو</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pl/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pl/strings.xml
new file mode 100644
index 0000000000..6c86763df5
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pl/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Czy odbierać powiadomienia od witryny „%1$s”?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Czy udostępnić obraz z aparatu witrynie „%1$s”?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Czy udostępnić dźwięk z mikrofonu witrynie „%1$s”?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Czy udostępnić witrynie „%1$s” informacje o położeniu?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Czy udostępnić obraz z aparatu i dźwięk z mikrofonu witrynie „%1$s”?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">1. mikrofon</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Tylny aparat</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Przedni aparat</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Zezwól</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Nie zezwalaj</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Nie pytaj ponownie na tej witrynie</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Zawsze</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nigdy</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Czy zezwolić witrynie „%1$s” na przechowywanie danych na urządzeniu?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Czy zezwolić witrynie „%1$s” na odtwarzanie treści chronionych przez DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Czy zezwolić witrynie „%1$s” na używanie swoich ciasteczek na witrynie „%2$s”?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Możesz zablokować dostęp, jeśli nie jest jasne, dlaczego witryna „%s” potrzebuje tych danych.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Zablokuj</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Więcej informacji</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rBR/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000000..39ffd54e09
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permitir que %1$s envie notificações?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permitir que %1$s use sua câmera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permitir que %1$s use seu microfone?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permitir que %1$s use sua localização?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permitir que %1$s use sua câmera e microfone?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfone 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Câmera traseira</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Câmera frontal</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Não permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Memorizar decisão para este site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Sempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Permitir ao %1$s armazenar dados em armazenamento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permitir que %1$s reproduza conteúdo controlado por direitos autorais?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permitir que %1$s use seus cookies em %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Você pode escolher bloquear o acesso, se não estiver claro o motivo de %s precisar desses dados.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saiba mais</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rPT/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000000..8e8be27325
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-pt-rPT/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permitir que %1$s envie notificações?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permitir que %1$s utilize a sua câmara?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permitir que %1$s utilize o seu microfone?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permitir que %1$s utilize a sua localização?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permitir que %1$s utilize a sua câmara e microfone?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfone 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Câmara traseira</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Câmara frontal</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permitir</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Não permitir</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Memorizar decisão para este site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Sempre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nunca</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Permitir que %1$s armazene dados no armazenamento persistente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permitir que %1$s reproduza conteúdo controlado por DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permitir que %1$s utilize os seus cookies em %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Pode bloquear o acesso se não for claro porque %s necessita destes dados.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloquear</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Saber mais</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-rm/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-rm/strings.xml
new file mode 100644
index 0000000000..4034b98ddb
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-rm/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permetter a %1$s da trametter communicaziuns?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permetter a %1$s da duvrar tia camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permetter a %1$s da duvrar tes microfon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permetter a %1$s dad acceder a tia posiziun?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permetter a %1$s da duvrar tia camera e tes microfon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Camera davos</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Camera davant</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permetter</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Betg permetter</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Memorisar la decisiun per questa website</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Adina</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Permetter a %1$s da memorisar datas en la memoria durabla?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Permetter a %1$s da reproducir cuntegn controllà da DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Permetter a %1$s dad utilisar ses cookies sin %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Igl è recumandabel da bloccar l\'access sch\'i n\'è betg cler pertge che %s dovra questas datas.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloccar</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Ulteriuras infurmaziuns</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ro/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ro/strings.xml
new file mode 100644
index 0000000000..00aa17bde3
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ro/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Permiți %1$s să trimită notificări?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Permiți %1$s să îți utilizeze camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Permiți %1$s să îți folosească microfonul?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Permiți %1$s să îți folosească locația?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Permiți %1$s să îți folosească microfonul și camera?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Cameră posterioară</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Cameră frontală</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permite</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Nu permite</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Ține minte decizia pentru acest site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Întotdeauna</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Niciodată</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ru/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ru/strings.xml
new file mode 100644
index 0000000000..3a0167b4b7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ru/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Разрешить %1$s отправлять уведомления?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Разрешить %1$s использовать вашу камеру?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Разрешить %1$s использовать ваш микрофон?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Разрешить %1$s использовать ваше местоположение?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Разрешить %1$s использовать вашу камеру и микрофон?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Микрофон 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Задняя камера</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Передняя камера</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Разрешить</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Не разрешать</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Запомнить для этого сайта</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Всегда</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Никогда</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Разрешить %1$s хранить данные в постоянном хранилище?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Разрешить %1$s воспроизводить защищённое авторским правом содержимое?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Разрешить %1$s использовать собственные куки на %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Вы можете заблокировать доступ, если не понимаете, зачем %s нужны эти данные.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Заблокировать</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Подробнее</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sat/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sat/strings.xml
new file mode 100644
index 0000000000..921025084f
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sat/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">ᱤᱛᱞᱟᱹᱭ ᱠᱩᱞ ᱞᱟᱹᱜᱤᱫ ᱛᱮ %1$s ᱦᱮᱥᱟᱨᱤᱭᱟᱹ ᱮᱢᱟᱭ ᱢᱮ?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">ᱟᱢᱟᱜ ᱠᱮᱢᱨᱟ ᱵᱮᱵᱷᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱛᱮ %1$s ᱦᱮᱥᱟᱨᱤᱭᱟᱹ ᱮᱢᱟᱭ ᱢᱮ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">ᱟᱢᱟᱜ ᱢᱟᱭᱠᱨᱚᱯᱷᱚᱱ ᱵᱮᱵᱷᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱛᱮ %1$s ᱦᱮᱥᱟᱨᱤᱭᱟᱹ ᱮᱢᱟᱭ ᱢᱮ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">ᱟᱢᱟᱜ ᱡᱟᱭᱜᱟ ᱵᱮᱵᱷᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱛᱮ %1$s ᱦᱮᱥᱟᱨᱤᱭᱟᱹ ᱮᱢᱟᱭ ᱢᱮ?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">ᱟᱢᱟᱜ ᱠᱮᱢᱨᱟ ᱟᱨ ᱢᱟᱭᱠᱨᱚᱯᱷᱚᱱ ᱵᱮᱵᱷᱟᱨ ᱞᱟᱹᱜᱤᱫ ᱛᱮ %1$s ᱦᱮᱥᱟᱨᱤᱭᱟᱹ ᱮᱢᱟᱭ ᱢᱮ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ᱢᱟᱭᱠᱨᱚᱯᱷᱚᱱ 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">ᱛᱟᱭᱚᱢ ᱠᱮᱢᱨᱟ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ᱥᱟᱢᱟᱝ ᱥᱮᱫᱟᱜ ᱠᱮᱢᱨᱟ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ᱦᱮᱥᱟᱹᱨᱤᱭᱟᱹ</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ᱟᱞᱚ ᱢᱟᱸᱡᱩᱨᱮᱭᱟᱢ</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ᱱᱤᱥᱴᱟᱹ ᱫᱤᱥᱚᱸ ᱫᱚᱦᱚᱭ ᱢᱮ ᱱᱚᱶᱟ ᱥᱟᱭᱤᱴ ᱞᱟᱹᱜᱤᱫ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ᱡᱟᱣᱜᱮ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ᱛᱤᱥ ᱦᱚᱸ ᱵᱟᱝ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title"> %1$s ᱵᱮᱥ ᱡᱟᱭᱜᱟ ᱨᱮ ᱰᱟᱴᱟ ᱫᱚᱦᱚ ᱪᱷᱚᱭᱮᱢ ᱥᱮ?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s DRM-ᱠᱚᱵᱽᱡᱟ ᱡᱤᱱᱤᱥ ᱠᱚ ᱯᱞᱮ ᱪᱷᱚ ᱞᱟᱹᱜᱤᱫ ᱚᱱᱩᱢᱚᱛᱤ ᱮᱢᱟᱭᱟ ᱥᱮ? </string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s ᱫᱚ %2$s ᱨᱮ ᱠᱩᱠᱤᱡᱽ ᱵᱮᱵᱷᱟᱨ ᱪᱷᱚᱣᱟᱭᱟᱢ ᱥᱮ ?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">ᱟᱢ ᱫᱚ ᱱᱚᱶᱟ ᱵᱞᱚᱠ ᱥᱮᱱᱟᱢ ᱠᱟᱱᱟ\ᱡᱩᱫᱤ ᱟᱢ ᱵᱟᱝ ᱵᱟᱲᱟᱭᱟᱢ %s ᱰᱟᱴᱟ ᱪᱮᱫᱟᱜ ᱫᱚᱨᱠᱟᱨ ᱠᱟᱱᱟ ᱾</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">ᱟᱠᱚᱴ</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ᱰᱷᱮᱨ ᱥᱮᱬᱟᱭ ᱢᱮ</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sc/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sc/strings.xml
new file mode 100644
index 0000000000..a8a2e9d0e8
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sc/strings.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Boles permìtere chi %1$s imbiet notìficas?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Boles permìtere chi %1$s impreet sa càmera tua?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Boles permìtere chi %1$s impreet su micròfonu tuo?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Boles permìtere chi %1$s impreet sa positzione tua?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Boles permìtere chi %1$s impreet sa càmera e su micròfonu tuos?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micròfonu 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Càmera posteriore</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Càmera anteriore</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Permite</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Non permitas</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Regorda sa detzisione pro custu situ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Semper</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Boles permìtere a %1$s de cunservare datos in s’archiviatzione permanente?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Boles permìtere a %1$s de reprodùere cuntenutos protetos dae DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Boles permìtere a %1$s de impreare is testimòngios suos in %2$s?</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloca</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Àteras informatziones</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-si/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-si/strings.xml
new file mode 100644
index 0000000000..da8e984bed
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-si/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s සඳහා දැනුම්දීම් යැවීමට ඉඩ දෙන්නද?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s සඳහා රූගතය භාවිතයට ඉඩ දෙන්නද?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s සඳහා ශබ්දවාහිනිය භාවිතයට ඉඩ දෙන්නද?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s සඳහා ස්ථානයට ප්‍රවේශයට ඉඩ දෙන්නද?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s සඳහා රූගතය හා ශබ්දවාහිනිය භාවිතයට ඉඩ දෙන්නද?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ශබ්දවාහිනිය 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">පසුපස රූගත උපාංගය</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ඉදිරිපස රූගත උපාංගය</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ඉඩ දෙන්න</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ඉඩ නොදෙන්න</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">අඩවිය සඳහා තීරණය මතක තබා ගන්න</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">සැමවිට</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">කවදාවත්</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s වෙත අනවරත ආචයනයේ දත්ත ගබඩා කිරීමට ඉඩ දෙන්නද?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s වෙත DRM-පාලිත අන්තර්ගත වාදනයට ඉඩ දෙන්නද?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s සඳහා එහි දත්තකඩ %2$s හි භාවිතයට ඉඩ දෙන්නද?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s වෙත මෙම දත්ත අවශ්‍ය වන්නේ මන්දැයි අපැහැදිලි නම් ඔබට ප්‍රවේශය අවහිර කිරීමට අවශ්‍ය විය හැකිය.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">අවහිර</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">තව දැනගන්න</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sk/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sk/strings.xml
new file mode 100644
index 0000000000..e0d95d238d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sk/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Chcete stránke %1$s povoliť odosielanie upozornení?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Chcete stránke %1$s povoliť používanie vašej kamery?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Chcete stránke %1$s povoliť používanie vášho mikrofónu?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Chcete stránke %1$s povoliť používanie vašej polohy?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Chcete stránke %1$s povoliť používanie vašej kamery a mikrofónu?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofón 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Zadná kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Predná kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Povoliť</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Nepovoliť</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Zapamätať si toto rozhodnutie pre túto stránku</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Vždy</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nikdy</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Chcete stránke %1$s povoliť ukladanie údajov do trvalého úložiska?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Chcete stránke %1$s povoliť prehrávanie obsahu chráneného pomocou DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Chcete povoliť stránke %1$s používať svoje súbory cookie aj na stránke %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Ak nie je jasné, prečo %s potrebuje tieto údaje, môžete jej prístup zakázať.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Zakázať</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Ďalšie informácie</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-skr/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-skr/strings.xml
new file mode 100644
index 0000000000..78fdd041e0
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-skr/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s کوں اطلاعاں پٹھݨ دی اجازت ݙیندے ہو؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s کوں آپݨاں کیمرہ ورتݨ دی اجازت ݙیندے ہو؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s کوں آپݨاں مائیکروفون ورتݨ دی اجازت ݙیندے ہو؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s کوں آپݨاں مقام ورتݨ دی اجازت ݙیندے ہو؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s کوں آپݨاں کیمرہ تے مائیکروفون ورتݨ دی اجازت ݙیندے ہو؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">مائیکروفون ١</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">پچھوں آلا کیمرہ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">سامھِݨے آلا کیمرہ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">اجازت ݙیوو</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">اجازت نہ ݙیوو</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">ایں سائٹ کیتے فیصلہ یاد رکھو</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ہمیشہ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">کݙاہیں نہ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s کوں مستقل ذخیرے وچ ڈیٹا ذخیرہ کرݨ دی اجازت ݙیووں؟</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s کوں ڈی آر ایم دے کنٹرول تھئے مواد چلاوݨ دی اجازت ݙیووں؟</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s کوں آپݨیاں کوکیاں %2$s تے ورتݨ دی اجازت ݙیووں؟</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">جے ایہ واضح کائنی جو %s کوں ایں ڈیٹا دی لوڑ کیوں ہے تاں تساں رسائی تے پابندی لاوݨ پسند کریسو۔</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">بلاک</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ٻیا سِکھو</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sl/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sl/strings.xml
new file mode 100644
index 0000000000..a8dbfd63fe
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sl/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Dovolite %1$s pošiljanje obvestil?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Dovolite %1$s uporabo kamere?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Dovolite %1$s uporabo mikrofona?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Dovolite %1$s uporabo lokacije?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Dovolite %1$s uporabo kamere in mikrofona?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Zadnja kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Sprednja kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Dovoli</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ne dovoli</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Zapomni si odločitev za to stran</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Vedno</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nikoli</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Dovolite strani %1$s shranjevati podatke v trajno shrambo?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Dovolite %1$s predvajanje vsebine, zaščitene z DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Ali dovolite %1$s uporabo svojih piškotkov na %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Če ni jasno, zakaj %s potrebuje te podatke, lahko zavrnete dostop.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Zavrni</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Več o tem</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sq/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sq/strings.xml
new file mode 100644
index 0000000000..8053f7e7f7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sq/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Të lejohet %1$s të dërgojë njoftime?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Të lejohet %1$s të përdorë kamerën tuaj?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Të lejohet %1$s të përdorë mikrofonin tuaj?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Të lejohet %1$s të përdorë vendndodhjen tuaj?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Të lejohet %1$s të përdorë kamerën dhe mikrofonin tuaj?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kamera e pasme</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kamera ballore</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Lejoje</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Mos e lejo</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Mbaje mend vendimin për këtë sajt</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Përherë</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Kurrë</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Të lejohet %1$s të depozitojë të dhëna në depozitë të qëndrueshme?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Të lejohet %1$s të luajë lëndë nën DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Të lejohet %1$s të përdorë cookie-t e veta në %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Mund të doni t’i bllokoni hyrjen, nëse s’është e qartë pse i duhen këto të dhëna %s.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bllokoje</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Mësoni më tepër</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sr/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sr/strings.xml
new file mode 100644
index 0000000000..4217960f6c
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sr/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Дазволити %1$s да шаље обавештења?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Дозволити %1$s да користи вашу камеру?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Дозволити %1$s да користи ваш микрофон?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Дозволити %1$s да користи вашу локацију?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Дозволити %1$s да користи вашу камеру и микрофон?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Микрофон 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Главна камера</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Предња камера</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Дозволи</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Не дозволи</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Запамти одлуку за ову страницу</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Увек</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Никад</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Дозволити %1$s да складишти податке у трајном складишту?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Дозволи %1$s да репродукује садржаја контролисаног DRM-ом?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Дозволи %1$s да користи своје колачиће на %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Размислите о блокирању приступа ако није јасно зашто %s треба ове податке.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Блокирај</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Сазнајте више</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-su/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-su/strings.xml
new file mode 100644
index 0000000000..54088a0c0e
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-su/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Idinan %1$s pikeun ngirim iber?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Idinan %1$s maké kaméra anjeun?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Idinan %1$s maké mikropon anjeun?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Idinan %1$s maké lokasi anjeun?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Idinan %1$s maké kaméra jeung mikropon anjeun?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikropon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kaméra tukang</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kaméra hareup</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Idinan</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Hulag</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Emut kaputusan pikeun ieu loka</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Matuh</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Kungsi</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Idinan %1$s pikeun nyimpen data dina panyimpenan anu tetep?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Idinan %1$s pikeun maénkeun kontén anu diatur ku DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Idinan %1$s maké réréméhna di %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Anjeun bisa meungpeuk aksés lamun teu puguh naha %s butuh ieu data.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Peungpeuk</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Lenyepan</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sv-rSE/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sv-rSE/strings.xml
new file mode 100644
index 0000000000..383ccd5344
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-sv-rSE/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Tillåt %1$s att skicka aviseringar?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Tillåt %1$s att använda din kamera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Tillåt %1$s att använda din mikrofon?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Tillåt %1$s att använda din plats?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Tillåt %1$s att använda din kamera och mikrofon?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kameran på baksidan av telefonen</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kameran på framsidan av telefonen</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Tillåt</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Tillåt inte</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Kom ihåg beslutet för denna webbplats</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Alltid</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Aldrig</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Tillåta %1$s att lagra data i beständig lagring?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Tillåt %1$s att spela DRM-kontrollerat innehåll?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Tillåt %1$s att använda kakor på %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Du kanske vill blockera åtkomst om det inte är klart varför %s behöver dessa data.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Blockera</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Läs mer</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ta/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ta/strings.xml
new file mode 100644
index 0000000000..4684de636b
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ta/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">அறிவிப்புகளை அனுப்ப %1$s ஐ அனுமதிக்கவா?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">உங்கள் படக்கருவியைப் பயன்படுத்த %1$s ஐ அனுமதிக்கவா?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">உங்கள் ஒலிவாங்கியைப் பயன்படுத்த %1$s ஐ அனுமதிக்கவா?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">உங்கள் இருப்பிடத்தைப் பயன்படுத்த %1$s ஐ அனுமதிக்கவா?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">உங்கள் படக்கருவியையும் ஒலிவாங்கியையும் பயன்படுத்த %1$s ஐ அனுமதிக்கவா?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ஒலிவாங்கி 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">பின்பக்கப் படக்கருவி</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">முன்பக்க புகைப்பட கருவி</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">அனுமதி</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">அனுமதிக்காதே</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">இந்த தளத்திற்கான முடிவை நினைவில் கொள்க</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">எப்போதும்</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ஒரு போதும் இல்லை</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">நிரந்தரச் சேமிப்பில் தரவைச் சேமிக்க %1$s தளத்தை அனுமதிக்கவா?</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-te/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-te/strings.xml
new file mode 100644
index 0000000000..3cff876a07
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-te/strings.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">గమనింపులను పంపడానికి %1$s‌ని అనుమతించాలా?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">మీ కెమెరా వాడటానికి %1$s‌ని అనుమతించాలా?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">మీ మైక్రోఫోను వాడటానికి %1$s‌ని అనుమతించాలా?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">మీ స్థానాన్ని చూడటానికి %1$s‌ని అనుమతించాలా?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">మీ కెమెరా, మైక్రోఫోన్లనూ వాడటానికి %1$sను అనుమతిస్తారా?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">మైక్రోఫోను 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">వెనుకవైపు కెమెరా</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ముందువైపు కెమెరా</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">అనుమతించు</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">అనుమతించవద్దు</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">నిర్ణయాన్ని ఈ సైటుకి గుర్తుంచుకో</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ఎల్లప్పుడూ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ఎప్పటికీకాదు</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">నిరంతర నిల్వలో డేటాను నిల్వ చేయడానికి %1$sని అనుమతించాలా?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">DRM- నియంత్రిత విషయాన్ని ప్లే చేయడానికి %1$s ని అనుమతించాలా?</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">నిరోధించు</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">ఇంకా తెలుసుకోండి</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tg/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tg/strings.xml
new file mode 100644
index 0000000000..a2a85c08d1
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tg/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Ба %1$s барои фиристодани огоҳномаҳо иҷозат медиҳед?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Ба %1$s барои истифодаи камераи шумо иҷозат медиҳед?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Ба %1$s барои истифодаи микрофони шумо иҷозат медиҳед?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Ба %1$s барои истифодаи ҷойгиршавии шумо иҷозат медиҳед?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Ба %1$s барои истифодаи камера ва микрофони шумо иҷозат медиҳед?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Микрофони 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Камераи қафо</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Камераи пеш</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Иҷозат додан</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Иҷозат дода нашавад</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Қарори ҷорӣ барои ин сомона дар хотир дошта шавад</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Ҳамеша</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Ҳеҷ гоҳ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Ба %1$s иҷозат медиҳед, ки маълумотро дар захирагоҳи доимӣ нигоҳ дорад?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Ба %1$s иҷозат медиҳед, ки муҳтавои идорашавандаи DRM-ро пахш кунад?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Ба %1$s иҷозат медиҳед, ки он кукиҳои худро дар %2$s истифода барад?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Шумо метавонед дастрасиро манъ кунед, агар маълум набошад, ки чаро ба %s ин маълумот лозим аст.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Манъ кардан</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Маълумоти бештар</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-th/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-th/strings.xml
new file mode 100644
index 0000000000..f39cdcaf6e
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-th/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">อนุญาตให้ %1$s ส่งการแจ้งเตือนหรือไม่?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">อนุญาตให้ %1$s ใช้กล้องของคุณหรือไม่?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">อนุญาตให้ %1$s ใช้ไมโครโฟนของคุณหรือไม่?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">อนุญาตให้ %1$s ใช้ตำแหน่งที่ตั้งของคุณหรือไม่?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">อนุญาตให้ %1$s ใช้กล้องและไมโครโฟนของคุณหรือไม่?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">ไมโครโฟน 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">กล้องหลัง</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">กล้องหน้า</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">อนุญาต</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">ไม่อนุญาต</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">จดจำการตัดสินใจสำหรับไซต์นี้</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">เสมอ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ไม่เลย</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">อนุญาตให้ %1$s จัดเก็บข้อมูลในที่เก็บข้อมูลถาวรหรือไม่?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">อนุญาตให้ %1$s เล่นเนื้อหาที่ควบคุมด้วย DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">อนุญาตให้ %1$s ใช้คุกกี้บน %2$s หรือไม่?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">คุณสามารถปิดกั้นการเข้าถึงได้หากคุณไม่แน่ใจเหตุผลที่ %s ต้องการข้อมูลนี้</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">ปิดกั้น</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">เรียนรู้เพิ่มเติม</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tl/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tl/strings.xml
new file mode 100644
index 0000000000..11210a1a26
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tl/strings.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Payagan ang %1$s na magpadala ng mga abiso?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Payagan ang %1$s na magamit ang iyong camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Payagan ang %1$s na magamit ang iyong mikropono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Payagan ang %1$s na magamit ang iyong lokasyon?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Payagan ang %1$s na magamit ang iyong camera at mikropono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikropono</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kamera sa likuran</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kamera sa harapan</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Payagan</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Huwag Payagan</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Tandaan ang desisyon para sa site na ito</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Palagi</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Hindi kailanman</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Payagan ang %1$s na mag-imbak ng data sa persistence storage?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Payagan ang %1$s na magpaandar ng DRM-controlled content?</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">I block</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Matuto pa</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tr/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tr/strings.xml
new file mode 100644
index 0000000000..1845aecafd
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tr/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s bildirim gönderebilsin mi?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s kameranızı kullanabilsin mi?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s mikrofonunuzu kullanabilsin mi?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s konumunuzu kullanabilsin mi?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s kameranızı ve mikrofonunuzu kullanabilsin mi?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Arka kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Ön kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">İzin ver</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">İzin verme</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Bu sitede bu kararımı hatırla</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Her zaman</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Asla</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s kalıcı depolama alanında veri depolayabilsin mi?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s sitesi DRM denetimli içerikleri oynatabilsin mi?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s, çerezlerini %2$s sitesinde kullanabilsin mi?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">%s sitesinin bu veriye neden ihtiyaç duyduğunu bilmiyorsanız erişimi engelleyebilirsiniz.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Engelle</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Daha fazla bilgi al</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-trs/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-trs/strings.xml
new file mode 100644
index 0000000000..7f29c0ce1a
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-trs/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Gā\'nïnt riña %1$s da\' gānātàj a\'ngô nuguan\' huā aj.</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Gā\'nïnt riña %1$s da\' gārasunj si kamarâ raj.</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Gā\'nïnt riña %1$s da\' gārasunj si āgâ\'t aga\' uxun nanèe aj.</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Gā\'nïnt riña %1$s da\' gārasunj lūguâ nun raj.</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Gā\'nïnt riña %1$s da\' gārasunj si kamarât ngà si āgâ\'t aga\' uxun nanèe aj.</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Aga\' uxun nanèe 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Kamarâ nù ne\' rūkùu</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Kamarâ nù ne\' ñāan</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Gā\'nïn</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Sī ga\'nïnjt</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Nanun ruhuâ nuguan\' nan guendâ sitiô nan</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Nīgànj chre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Nitāj āmān</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Gā\’nïnt riña %1$s da\' nachra chre\’ nâ man nej datô huā aj.</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Gā’nïnt riña %1$s da’ dūguachrá man sa dugumîn DRM aj.</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Gā’nïnt riña %1$s da’ gārasun man nej si kokij riña %2$s aj.</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Si gūruhuaj nī nāránt ña gātūt nan dadin’ sa gū’nàj %s achín nej si datôt.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Garûn\'</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Gāhuin chrūn doj</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tt/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tt/strings.xml
new file mode 100644
index 0000000000..be1cf0bb70
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tt/strings.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s искәртүләр җибәрә алсынмы?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s камерагызны куллана алсынмы?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s микрофоныгызны куллана алсынмы?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s урнашуыгызны куллана алсынмы?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s камера һәм микрофоныгызны куллана алсынмы?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Микрофон 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Арткы камера</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Алгы камера</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Рөхсәт итү</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Рөхсәт итмәү</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Бу сайт өчен карарны истә калдыру</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Һәрвакыт</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Беркайчан да</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s мәгълүматларны даими саклагычка саклый алсынмы?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s сайты DRM-лы эчтәлекләрне уйната алсынмы?</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Блоклау</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Күбрәк белү</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tzm/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tzm/strings.xml
new file mode 100644
index 0000000000..aab9240198
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-tzm/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">ssureg %1$s ad yazen tineɣmisin?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">ssureg %1$s ad issemres takamṛa-nnek?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">ssureg %1$s ad issemres amikṛu-nnek?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">ssureg %1$s ad issemres tansa-nnek?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">ssureg %1$s ad issemres takamṛa d umikṛu-nnek?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Amikṛu1</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">ssureg</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ad ur ssirig</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Kti taɣtast n usmel-a</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Abda</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Usar</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Isin uggar</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ug/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ug/strings.xml
new file mode 100644
index 0000000000..023a260377
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ug/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s نىڭ ئۇقتۇرۇش ئەۋەتىشىگە يول قويامدۇ؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s كامېرايىڭىزنى ئىشلىتىشىگە يول قويامسىز؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s مىكروفونىڭىزنى ئىشلىتىشىگە يول قويامسىز؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s ئورنىڭىزنى ئىشلىتىشىگە يول قويامسىز؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s كامېرا ۋە مىكروفونىڭىزنى ئىشلىتىشىگە يول قويامسىز؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">مىكروفون 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">ئارقا كامېرا</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">ئالدى كامېرا</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">يول قوي</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">رۇخسەت بەرمە</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">بۇ بېكەتتىكى قارارىڭىزنى ئەستە تۇتىدۇ</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ھەمىشە</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">ھىچقاچان</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$s سانلىق مەلۇماتلارنى ئىزچىل ساقلىشىغا يول قويامدۇ؟</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">DRM تىزگىنلىنىدىغان مەزمۇننى %1$s نىڭ قويۇشىغا يول قويامدۇ؟</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%2$s دىكى cookies نى %1$s نىڭ ئىشلىتىشىگە يول قويامدۇ؟</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">ئەگەر %s بۇ سانلىق مەلۇماتلارنى نېمىگە ئىشلىتىدىغانلىقىنىڭ سەۋەبىنى ئېنىق بايان قىلمىسا، ئۇنى چەكلىشىڭىز كېرەك.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">توسۇش</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">تەپسىلاتى</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uk/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000000..bccd8857bf
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uk/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Дозволити %1$s надсилати сповіщення?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Дозволити %1$s використовувати вашу камеру?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Дозволити %1$s використовувати ваш мікрофон?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Дозволити %1$s використовувати ваше розташування?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Дозволити %1$s використовувати ваші камеру й мікрофон?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Мікрофон 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Задня камера</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Передня камера</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Дозволити</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Не дозволяти</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Запам’ятати рішення для цього сайту</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Завжди</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Ніколи</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Дозволити %1$s зберігати дані у постійному сховищі?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Дозволити %1$s відтворювати вміст, контрольований DRM?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Дозволити %1$s використовувати свої файли cookie на %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Ви можете заблокувати доступ, якщо вам незрозуміло, нащо %s потребує ці дані.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Заблокувати</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Докладніше</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ur/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ur/strings.xml
new file mode 100644
index 0000000000..c8b1a68726
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-ur/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s کو اطلاعات بھیجنے کی اجازت دیں؟</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s کو اپنا کیمرا استعمال کرنے کی اجازت دیں؟</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s کو اپنا مائکروفون استعمال کرنے کی اجازت دیں؟</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s کو اپنا محل وقوع جاننے کی اجازت دیں؟</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s کو اپنا کیمرا اور مائکروفون کا استعمال کرنے کی اجازت دیں؟</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one"> 1مائیکروفون</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">پیچھے والا کیمرہ</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">سامنے والا کیمرہ</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">اجازت دیں</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">اجازت مت دیں</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">اس سائٹ کے بارے میں فیصلہ یاد رکھیں</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">ہمیشہ</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">کبھی نہیں</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">%1$s کو DRM کے زیر کنٹرول شدہ مواد چلانے کی اجازت دیں؟</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">مزید سیکھیں</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uz/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uz/strings.xml
new file mode 100644
index 0000000000..a43e77b301
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-uz/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">%1$s bildirishnomalar yuborishga ruxsat berilsinmi?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">%1$s kameradan foydalanishiga ruxsat berilsinmi?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">%1$s mikrofondan foydalanishiga ruxsat berilsinmi?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">%1$s joylashuv axborotidan foydalanishi uchun ruxsat berilsinmi?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">%1$s kamera va mikrofondan foydalanishiga ruxsat berilsinmi?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Mikrofon 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Orqa kamera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Old kamera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Ruxsat berish</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Ruxsat berilmasin</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Bu sayt uchun qaror eslab qolinsin</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Doimo</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Hech qachon</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">%1$sga maʼlumotlarni mavjud xotiraga joylashga ruxsat berilsinmi?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">DRM tomonidan boshqariladigan kontentni %1$s ishga tushirishiga ruxsat berilsinmi?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">%1$s saytiga %2$s saytidagi cookie fayllardan foydalansihga ruxsat berasizmi?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Agar bu maʼlumotlar %s saytiga nima uchun kerakligi aniq boʻlmasa, kirishni bloklashingiz mumkin.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Bloklash</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Batafsil</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vec/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vec/strings.xml
new file mode 100644
index 0000000000..7d3f70a8d7
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vec/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Parmeti a %1$s de mandare notifeghe?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Pasrmeti a %1$s de uxare ƚa to teƚecamera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Parmeti a %1$s de uxare el to microfono?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Parmeti a %1$s de uxare ƚa to poxision?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Parmeti a %1$s de uxare ƚa to camera e el to microfono?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microfono 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Teƚecamera de drio</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Teƚecamera de davanti</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Parmeti</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">No parmetere</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Ricordate ƚa decixion par sto sito</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Senpre</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Mai</string>
+ </resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vi/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vi/strings.xml
new file mode 100644
index 0000000000..537c8d41cb
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-vi/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Cho phép %1$s gửi thông báo?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Cho phép %1$s sử dụng máy ảnh của bạn?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Cho phép %1$s sử dụng micrô của bạn?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Cho phép %1$s sử dụng vị trí của bạn?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Cho phép %1$s sử dụng máy ảnh và micrô của bạn?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Micrô 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Máy ảnh sau</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Máy ảnh trước</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Cho phép</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Không cho phép</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Ghi nhớ quyết định cho trang web này</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Luôn luôn</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Không bao giờ</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Cho phép %1$s lưu trữ dữ liệu trong bộ nhớ lâu dài?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Cho phép %1$s phát nội dung được DRM bảo vệ?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Cho phép %1$s sử dụng cookie của nó trên %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">Bạn có thể muốn chặn truy cập nếu không rõ tại sao %s cần dữ liệu này.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Chặn</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Tìm hiểu thêm</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-yo/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-yo/strings.xml
new file mode 100644
index 0000000000..ca9ed2c180
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-yo/strings.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Fàyègba %1$s láti fi àwọn ìtanilólobó ráńṣẹ́?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Fàyègba %1$s láti lo èrọ-ayàwòrán rẹ?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Fàyègba %1$s láti lo ẹ̀rọ-ìgbóhùn rẹ?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Gbà láàyè %1$s láti lo ibi tí o wà?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Fàyègba %1$s láti lo ẹ̀rọ-ayàwòrán àti ẹ̀rọ-ìgbóhùn rẹ?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Ẹ̀rọ-ìgbóhùn 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Ẹ̀rọ-ayàwòrán tó ń kọjú-sẹ́hìn</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Ẹ̀rọ-ayàwòrán tó ń kojú-síwájú</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Fàyègbà</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Má ṣe fàyègbà</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Rántí ìpinnu fún sáìtì yí</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Ní gbogbo ìgbà</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Láéláé</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Fàyègba %1$s láti fi dátà pamọ́ sí àyè tó dúróore?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Fàyègba %1$s láti mú àkóónú ìṣàkóso DRM ṣiṣẹ́ bí?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Falyègba %1$s láti lo àwọn kúkì rẹ̀ lórí %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">O lè fẹ́ dẹ̀nà ìwọlé tó bá rú ọ lójú ìdí %s tó fi nílò dátà yí.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Dẹ̀nà</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Kẹ́kọ̀ọ́ si</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rCN/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000000..6f5f603c5d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rCN/strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">要允许 %1$s 发送通知吗?</string>
+
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">要允许 %1$s 使用您的相机吗?</string>
+
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">要允许 %1$s 使用您的麦克风吗?</string>
+
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">要允许 %1$s 获取您的位置吗?</string>
+
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">要允许 %1$s 使用您的相机和麦克风吗?</string>
+
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">麦克风 1</string>
+
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">后置摄像头</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">前置摄像头</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">允许</string>
+
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">不允许</string>
+
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">记住对此网站的决定</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">总是</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">一律拒绝</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">要允许 %1$s 持久存储数据吗?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">要允许 %1$s 播放受 DRM 控制的内容吗?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">要允许 %1$s 在 %2$s 上使用它自己的 Cookie 吗?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">若 %s 未明确阐述需要此数据的原因,您应该阻止它。</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">阻止</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">详细了解</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rTW/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000000..f8ec799bf0
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">要允許 %1$s 傳送通知嗎?</string>
+
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">要允許 %1$s 使用您的攝影機嗎?</string>
+
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">要允許 %1$s 使用您的麥克風嗎?</string>
+
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">要允許 %1$s 知道您的所在位置嗎?</string>
+
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">要允許 %1$s 使用您的攝影機與麥克風嗎?</string>
+
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">1 號麥克風</string>
+
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">後鏡頭</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">前鏡頭</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">允許</string>
+
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">不允許</string>
+
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">對此網站記住我的決定</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">總是</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">永不</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">要允許 %1$s 將資料儲存於持續性儲存空間嗎?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">要允許 %1$s 播放 DRM 控制的內容嗎?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">要允許 %1$s 在 %2$s 上使用該網站自己的 cookie 嗎?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">如果 %s 沒有清楚解釋為什麼需要此資料,您應該封鎖它。</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">封鎖</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">了解更多</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values/strings.xml b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..4fdaeb3721
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/main/res/values/strings.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<resources>
+ <!-- Title of a dialog for a notification permission request. -->
+ <string name="mozac_feature_sitepermissions_notification_title">Allow %1$s to send notifications?</string>
+ <!-- Title of a dialog for a camera permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_title">Allow %1$s to use your camera?</string>
+ <!-- Title of a dialog for a microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_microfone_title">Allow %1$s to use your microphone?</string>
+ <!-- Title of a dialog for a location permission request. -->
+ <string name="mozac_feature_sitepermissions_location_title">Allow %1$s to use your location?</string>
+ <!-- Title of a dialog for a camera and microphone permission request. -->
+ <string name="mozac_feature_sitepermissions_camera_and_microphone">Allow %1$s to use your camera and microphone?</string>
+ <!-- Option in a dialog for requesting a microphone permission, this option will give access to
+ the first microphone-->
+ <string name="mozac_feature_sitepermissions_option_microphone_one">Microphone 1</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ back facing camera-->
+ <string name="mozac_feature_sitepermissions_back_facing_camera2">Rear-facing camera</string>
+ <!-- Option in a dialog for requesting a camera permission, this option will give access to
+ front facing camera-->
+ <string name="mozac_feature_sitepermissions_selfie_camera2">Front-facing camera</string>
+ <!-- Text for a positive button in a permission request dialog, this button will give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_allow">Allow</string>
+ <!-- Text for a negative button in a permission request dialog, this button will do not give
+ access to this permission-->
+ <string name="mozac_feature_sitepermissions_not_allow">Don’t allow</string>
+ <!-- Text for a checkbox in a permission request dialog, this will allow to not show again the prompt-->
+ <string name="mozac_feature_sitepermissions_do_not_ask_again_on_this_site2">Remember decision for this site</string>
+ <!-- Text for a positive button in a permission request dialog. This will always allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_always_allow">Always</string>
+ <!-- Text for a negative button in a permission request dialog. This will never allow and remember the decision of the user, this is the special case of the notification permission, that is only ask one time-->
+ <string name="mozac_feature_sitepermissions_never_allow">Never</string>
+ <!-- Title of a dialog to require to save data in persistent storage. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_persistent_storage_title">Allow %1$s to store data in persistent storage?</string>
+ <!-- Title of a dialog to use EME. %1$s will be replaced with the URL of the current page -->
+ <string name="mozac_feature_sitepermissions_media_key_system_access_title">Allow %1$s to play DRM-controlled content?</string>
+ <!-- Title of a dialog to use cross origin storage permission. %1$s is the name of the site URL (www.site1.example) trying to track the user's activity.
+ %2$s is the name of the site URL (www.site2.example) that the user is visiting. This is the same domain name displayed in the address bar -->
+ <string name="mozac_feature_sitepermissions_storage_access_title">Allow %1$s to use its cookies on %2$s?</string>
+ <!-- Message of a dialog offering more context about the cross origin storage permission.
+ %s is the name of the site URL (www.site1.example) trying to track the user's activity. -->
+ <string name="mozac_feature_sitepermissions_storage_access_message">You may want to block access if it\'s not clear why %s needs this data.</string>
+ <!-- Text for a negative button in the storage access permission request dialog. This button will not give access to this permission. -->
+ <string name="mozac_feature_sitepermissions_storage_access_not_allow">Block</string>
+ <!-- Clickable text that will open a new tab navigating the user to online documentation about specific features. -->
+ <string name="mozac_feature_sitepermissions_learn_more_title">Learn more</string>
+</resources>
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorageTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorageTest.kt
new file mode 100644
index 0000000000..aef533b39e
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/OnDiskSitePermissionsStorageTest.kt
@@ -0,0 +1,251 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import android.os.Looper.getMainLooper
+import androidx.paging.DataSource
+import androidx.room.DatabaseConfiguration
+import androidx.room.InvalidationTracker
+import androidx.sqlite.db.SupportSQLiteOpenHelper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import kotlinx.coroutines.test.runTest
+import mozilla.components.concept.engine.DataCleanable
+import mozilla.components.concept.engine.Engine.BrowsingData
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.BLOCKED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.NO_DECISION
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.AUTOPLAY_AUDIBLE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.AUTOPLAY_INAUDIBLE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.BLUETOOTH
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.CAMERA
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.LOCAL_STORAGE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.LOCATION
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.MICROPHONE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.NOTIFICATION
+import mozilla.components.feature.sitepermissions.db.SitePermissionsDao
+import mozilla.components.feature.sitepermissions.db.SitePermissionsDatabase
+import mozilla.components.feature.sitepermissions.db.SitePermissionsEntity
+import mozilla.components.support.test.any
+import mozilla.components.support.test.mock
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.robolectric.Shadows.shadowOf
+
+@RunWith(AndroidJUnit4::class)
+class OnDiskSitePermissionsStorageTest {
+
+ private lateinit var mockDAO: SitePermissionsDao
+ private lateinit var storage: OnDiskSitePermissionsStorage
+ private lateinit var mockDataCleanable: DataCleanable
+
+ @Before
+ fun setup() {
+ mockDAO = mock()
+ mockDataCleanable = mock()
+ storage = spy(
+ OnDiskSitePermissionsStorage(mock(), mockDataCleanable).apply {
+ databaseInitializer = { mockDatabase(mockDAO) }
+ },
+ )
+ }
+
+ @Test
+ fun `save a new SitePermission`() = runTest {
+ val sitePermissions = createNewSitePermission()
+
+ storage.save(sitePermissions, private = false)
+
+ verify(mockDAO).insert(any())
+ }
+
+ @Test
+ fun `GIVEN a private permission WHEN save THEN the SitePermission is not store`() = runTest {
+ val sitePermissions = createNewSitePermission()
+
+ storage.save(sitePermissions, private = true)
+
+ verify(mockDAO, times(0)).insert(any())
+ }
+
+ @Test
+ fun `update a SitePermission`() = runTest {
+ val sitePermissions = createNewSitePermission()
+
+ storage.update(sitePermissions, private = false)
+ shadowOf(getMainLooper()).idle()
+
+ verify(mockDAO).update(any())
+ verify(mockDataCleanable).clearData(BrowsingData.select(BrowsingData.PERMISSIONS), sitePermissions.origin)
+ }
+
+ @Test
+ fun `GIVEN a private permission WHEN update THEN the SitePermission is not store`() = runTest {
+ val sitePermissions = createNewSitePermission()
+
+ storage.update(sitePermissions, private = true)
+ shadowOf(getMainLooper()).idle()
+
+ verify(mockDAO, times(0)).update(any())
+ verify(mockDataCleanable, times(0)).clearData(
+ BrowsingData.select(BrowsingData.PERMISSIONS),
+ sitePermissions.origin,
+ )
+ }
+
+ @Test
+ fun `find a SitePermissions by origin`() = runTest {
+ storage.findSitePermissionsBy("mozilla.org", private = false)
+
+ verify(mockDAO).getSitePermissionsBy("mozilla.org")
+ }
+
+ @Test
+ fun `GIVEN private sitePermissions WHEN findSitePermissionsBy THEN reset SitePermissions`() =
+ runTest {
+ val dbPermission = SitePermissionsEntity(
+ origin = "mozilla.dev",
+ localStorage = ALLOWED,
+ crossOriginStorageAccess = ALLOWED,
+ location = BLOCKED,
+ notification = NO_DECISION,
+ microphone = ALLOWED,
+ camera = BLOCKED,
+ bluetooth = ALLOWED,
+ autoplayAudible = AutoplayStatus.BLOCKED,
+ autoplayInaudible = AutoplayStatus.BLOCKED,
+ mediaKeySystemAccess = NO_DECISION,
+ savedAt = 0,
+ )
+
+ doReturn(dbPermission).`when`(mockDAO)
+ .getSitePermissionsBy(origin = dbPermission.origin)
+
+ val foundPermissions =
+ storage.findSitePermissionsBy(dbPermission.origin, private = true)
+
+ assertNull(foundPermissions)
+ }
+
+ @Test
+ fun `find all sitePermissions grouped by permission`() = runTest {
+ doReturn(dummySitePermissionEntitiesList())
+ .`when`(mockDAO).getSitePermissions()
+
+ val map = storage.findAllSitePermissionsGroupedByPermission()
+
+ verify(mockDAO).getSitePermissions()
+
+ assertEquals(2, map[LOCAL_STORAGE]?.size)
+ assertFalse(LOCATION in map)
+ assertFalse(NOTIFICATION in map)
+ assertFalse(CAMERA in map)
+ assertFalse(AUTOPLAY_AUDIBLE in map)
+ assertFalse(AUTOPLAY_INAUDIBLE in map)
+ assertEquals(2, map[BLUETOOTH]?.size)
+ assertEquals(2, map[MICROPHONE]?.size)
+ }
+
+ @Test
+ fun `remove a SitePermissions`() = runTest {
+ val sitePermissions = createNewSitePermission()
+
+ storage.remove(sitePermissions, private = false)
+
+ shadowOf(getMainLooper()).idle()
+
+ verify(mockDAO).deleteSitePermissions(any())
+ verify(mockDataCleanable).clearData(BrowsingData.select(BrowsingData.PERMISSIONS), sitePermissions.origin)
+ }
+
+ @Test
+ fun `remove all SitePermissions`() = runTest {
+ storage.removeAll()
+ shadowOf(getMainLooper()).idle()
+
+ verify(mockDAO).deleteAllSitePermissions()
+ verify(mockDataCleanable).clearData(BrowsingData.select(BrowsingData.PERMISSIONS))
+ }
+
+ @Test
+ fun `get all SitePermissions paged`() = runTest {
+ val mockDataSource: DataSource<Int, SitePermissionsEntity> = mock()
+
+ doReturn(
+ object : DataSource.Factory<Int, SitePermissionsEntity>() {
+ override fun create(): DataSource<Int, SitePermissionsEntity> {
+ return mockDataSource
+ }
+ },
+ ).`when`(mockDAO).getSitePermissionsPaged()
+
+ storage.getSitePermissionsPaged()
+
+ verify(mockDAO).getSitePermissionsPaged()
+ }
+
+ private fun createNewSitePermission(): SitePermissions {
+ return SitePermissions(
+ origin = "mozilla.dev",
+ localStorage = ALLOWED,
+ location = BLOCKED,
+ notification = NO_DECISION,
+ microphone = NO_DECISION,
+ camera = NO_DECISION,
+ bluetooth = ALLOWED,
+ savedAt = 0,
+ )
+ }
+
+ private fun dummySitePermissionEntitiesList(): List<SitePermissionsEntity> {
+ return listOf(
+ SitePermissionsEntity(
+ origin = "mozilla.dev",
+ localStorage = ALLOWED,
+ crossOriginStorageAccess = ALLOWED,
+ location = BLOCKED,
+ notification = NO_DECISION,
+ microphone = ALLOWED,
+ camera = BLOCKED,
+ bluetooth = ALLOWED,
+ autoplayAudible = AutoplayStatus.BLOCKED,
+ autoplayInaudible = AutoplayStatus.BLOCKED,
+ mediaKeySystemAccess = NO_DECISION,
+ savedAt = 0,
+ ),
+ SitePermissionsEntity(
+ origin = "mozilla.dev",
+ localStorage = ALLOWED,
+ crossOriginStorageAccess = ALLOWED,
+ location = BLOCKED,
+ notification = NO_DECISION,
+ microphone = ALLOWED,
+ camera = BLOCKED,
+ bluetooth = ALLOWED,
+ autoplayAudible = AutoplayStatus.BLOCKED,
+ autoplayInaudible = AutoplayStatus.BLOCKED,
+ mediaKeySystemAccess = NO_DECISION,
+ savedAt = 0,
+ ),
+ )
+ }
+
+ private fun mockDatabase(dao: SitePermissionsDao) = object : SitePermissionsDatabase() {
+ override fun sitePermissionsDao() = dao
+
+ override fun createOpenHelper(config: DatabaseConfiguration): SupportSQLiteOpenHelper = mock()
+ override fun createInvalidationTracker(): InvalidationTracker = mock()
+ override fun clearAllTables() = Unit
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragmentTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragmentTest.kt
new file mode 100644
index 0000000000..6e55cc002d
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragmentTest.kt
@@ -0,0 +1,481 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import android.view.Gravity.TOP
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.CheckBox
+import android.widget.TextView
+import androidx.core.view.isVisible
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentTransaction
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.feature.sitepermissions.SitePermissionsFeature.PromptsStyling
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.doNothing
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import androidx.core.R as coreR
+
+@RunWith(AndroidJUnit4::class)
+class SitePermissionsDialogFragmentTest {
+
+ private val permissionRequestId = "permissionID"
+ private val titleIcon = coreR.drawable.notification_icon_background
+
+ @Test
+ fun `build dialog`() {
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = true,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val checkBox = dialog.findViewById<CheckBox>(R.id.do_not_ask_again)
+
+ assertTrue("Checkbox should be displayed", checkBox.isVisible)
+ assertFalse("Checkbox shouldn't be checked", checkBox.isChecked)
+ assertFalse("User selection property should be false", fragment.userSelectionCheckBox)
+ }
+
+ @Test
+ fun `display dialog with unselected 'don't ask again'`() {
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = true,
+ shouldSelectDoNotAskAgainCheckBox = false,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val checkBox = dialog.findViewById<CheckBox>(R.id.do_not_ask_again)
+
+ assertTrue("Checkbox should be displayed", checkBox.isVisible)
+ assertFalse("Checkbox shouldn't be checked", checkBox.isChecked)
+ assertFalse("User selection property should be false", fragment.userSelectionCheckBox)
+ }
+
+ @Test
+ fun `display dialog with preselected 'don't ask again'`() {
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = true,
+ shouldSelectDoNotAskAgainCheckBox = true,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val checkBox = dialog.findViewById<CheckBox>(R.id.do_not_ask_again)
+
+ assertTrue("Checkbox should be displayed", checkBox.isVisible)
+ assertTrue("Checkbox should be checked", checkBox.isChecked)
+ assertTrue("User selection property should be true", fragment.userSelectionCheckBox)
+ }
+
+ @Test
+ fun `dialog with shouldShowDoNotAskAgainCheckBox equals false should not have a checkbox`() {
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = false,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val checkBox = dialog.findViewById<CheckBox>(R.id.do_not_ask_again)
+
+ assertFalse("Checkbox shouldn't be displayed", checkBox.isVisible)
+ assertFalse("User selection property should be false", fragment.userSelectionCheckBox)
+ }
+
+ @Test
+ fun `dialog with a default null message should not have a message section`() {
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = false,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val message = dialog.findViewById<TextView>(R.id.message)
+
+ assertFalse("Message shouldn't be displayed", message.isVisible)
+ }
+
+ @Test
+ fun `dialog with passed in message should display that message`() {
+ val expectedMessage = "This is just a test"
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = false,
+ message = expectedMessage,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val message = dialog.findViewById<TextView>(R.id.message)
+
+ assertTrue("Message should be displayed", message.isVisible)
+ assertEquals(expectedMessage, message.text)
+ }
+
+ @Test
+ fun `dialog with a default shouldShowLearnMoreLink being equal to false should not have a Learn more link`() {
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = false,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val learnMoreLink = dialog.findViewById<TextView>(R.id.learn_more)
+
+ assertFalse("Learn more link shouldn't be displayed", learnMoreLink.isVisible)
+ }
+
+ @Test
+ fun `dialog with shouldShowLearnMoreLink equals true should show a properly configured Learn more link`() {
+ val feature: SitePermissionsFeature = mock()
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = feature,
+ shouldShowDoNotAskAgainCheckBox = false,
+ shouldShowLearnMoreLink = true,
+ ),
+ )
+ doNothing().`when`(fragment).dismiss()
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val learnMoreLink = dialog.findViewById<TextView>(R.id.learn_more)
+
+ assertTrue("Learn more link shouldn't be displayed", learnMoreLink.isVisible)
+ assertFalse("Learn more link should not be long clickable", learnMoreLink.isLongClickable)
+ learnMoreLink.callOnClick()
+ verify(fragment).dismiss()
+ verify(feature).onLearnMorePress(permissionRequestId, "sessionId")
+ }
+
+ @Test
+ fun `clicking on positive button notifies the feature (temporary)`() {
+ val mockFeature: SitePermissionsFeature = mock()
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mockFeature,
+ shouldShowDoNotAskAgainCheckBox = false,
+ shouldSelectDoNotAskAgainCheckBox = false,
+ ),
+ )
+ doNothing().`when`(fragment).dismiss()
+
+ fragment.feature = mockFeature
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val positiveButton = dialog.findViewById<Button>(R.id.allow_button)
+ positiveButton.performClick()
+ verify(mockFeature).onPositiveButtonPress(permissionRequestId, "sessionId", false)
+ }
+
+ @Test
+ fun `dismissing the dialog notifies the feature`() {
+ val mockFeature: SitePermissionsFeature = mock()
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mockFeature,
+ shouldShowDoNotAskAgainCheckBox = false,
+ shouldSelectDoNotAskAgainCheckBox = false,
+ ),
+ )
+ doNothing().`when`(fragment).dismiss()
+
+ fragment.feature = mockFeature
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ doReturn(mockFragmentManager()).`when`(fragment).parentFragmentManager
+
+ fragment.onDismiss(mock())
+
+ verify(mockFeature).onDismiss(permissionRequestId, "sessionId")
+ }
+
+ fun `dialog with passed in text for the negative button should use it`() {
+ val expectedText = "This is just a test"
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = false,
+ negativeButtonText = expectedText,
+ ),
+ )
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val negativeButton = dialog.findViewById<Button>(R.id.deny_button)
+ assertEquals(expectedText, negativeButton.text)
+ }
+
+ fun `dialog with a text for the negative button not passed has a default available`() {
+ val expectedText = testContext.getString(R.string.mozac_feature_sitepermissions_not_allow)
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = false,
+ ),
+ )
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val negativeButton = dialog.findViewById<Button>(R.id.deny_button)
+ assertEquals(expectedText, negativeButton.text)
+ }
+
+ @Test
+ fun `clicking on negative button notifies the feature (temporary)`() {
+ val mockFeature: SitePermissionsFeature = mock()
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mockFeature,
+ shouldShowDoNotAskAgainCheckBox = false,
+ shouldSelectDoNotAskAgainCheckBox = false,
+ ),
+ )
+ doNothing().`when`(fragment).dismiss()
+
+ fragment.feature = mockFeature
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val positiveButton = dialog.findViewById<Button>(R.id.deny_button)
+ positiveButton.performClick()
+ verify(mockFeature)
+ .onNegativeButtonPress(permissionRequestId, "sessionId", false)
+ }
+
+ @Test
+ fun `clicking on positive button notifies the feature (permanent)`() {
+ val mockFeature: SitePermissionsFeature = mock()
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mockFeature,
+ shouldShowDoNotAskAgainCheckBox = false,
+ shouldSelectDoNotAskAgainCheckBox = true,
+ ),
+ )
+ doNothing().`when`(fragment).dismiss()
+
+ fragment.feature = mockFeature
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val positiveButton = dialog.findViewById<Button>(R.id.allow_button)
+ positiveButton.performClick()
+ verify(mockFeature)
+ .onPositiveButtonPress(permissionRequestId, "sessionId", true)
+ }
+
+ @Test
+ fun `clicking on negative button notifies the feature (permanent)`() {
+ val mockFeature: SitePermissionsFeature = mock()
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mockFeature,
+ shouldShowDoNotAskAgainCheckBox = false,
+ shouldSelectDoNotAskAgainCheckBox = true,
+ ),
+ )
+ doNothing().`when`(fragment).dismiss()
+
+ fragment.feature = mockFeature
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val positiveButton = dialog.findViewById<Button>(R.id.deny_button)
+ positiveButton.performClick()
+ verify(mockFeature)
+ .onNegativeButtonPress(permissionRequestId, "sessionId", true)
+ }
+
+ @Test
+ fun `dialog must have all the styles of the feature promptsStyling object`() {
+ val mockFeature: SitePermissionsFeature = mock()
+
+ doReturn(PromptsStyling(TOP, true)).`when`(mockFeature).promptsStyling
+
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mockFeature,
+ shouldShowDoNotAskAgainCheckBox = false,
+ ),
+ )
+
+ fragment.feature = mockFeature
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+
+ val dialogAttributes = dialog.window!!.attributes
+
+ assertTrue(dialogAttributes.gravity == TOP)
+ assertTrue(dialogAttributes.width == ViewGroup.LayoutParams.MATCH_PARENT)
+ }
+
+ @Test
+ fun `dialog with isNotificationRequest equals true should not have a checkbox`() {
+ val fragment = spy(
+ SitePermissionsDialogFragment.newInstance(
+ "sessionId",
+ "title",
+ titleIcon,
+ permissionRequestId = permissionRequestId,
+ feature = mock(),
+ shouldShowDoNotAskAgainCheckBox = true,
+ shouldSelectDoNotAskAgainCheckBox = false,
+ isNotificationRequest = true,
+ ),
+ )
+
+ doReturn(testContext).`when`(fragment).requireContext()
+
+ val dialog = fragment.onCreateDialog(null)
+ dialog.show()
+
+ val checkBox = dialog.findViewById<CheckBox>(R.id.do_not_ask_again)
+
+ assertFalse("Checkbox shouldn't be displayed", checkBox.isVisible)
+ assertTrue("User selection property should be true", fragment.userSelectionCheckBox)
+ }
+
+ private fun mockFragmentManager(): FragmentManager {
+ val fragmentManager: FragmentManager = mock()
+ val transaction: FragmentTransaction = mock()
+ doReturn(transaction).`when`(fragmentManager).beginTransaction()
+ return fragmentManager
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFactsTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFactsTest.kt
new file mode 100644
index 0000000000..f57911594a
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFactsTest.kt
@@ -0,0 +1,116 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import mozilla.components.concept.engine.permission.Permission.AppCamera
+import mozilla.components.concept.engine.permission.Permission.AppLocationFine
+import mozilla.components.concept.engine.permission.Permission.ContentAudioCapture
+import mozilla.components.concept.engine.permission.Permission.ContentCrossOriginStorageAccess
+import mozilla.components.concept.engine.permission.Permission.ContentVideoCapture
+import mozilla.components.concept.engine.permission.Permission.Generic
+import mozilla.components.support.base.Component.FEATURE_SITEPERMISSIONS
+import mozilla.components.support.base.facts.Action
+import mozilla.components.support.base.facts.processor.CollectionProcessor
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class SitePermissionsFactsTest {
+
+ @Test
+ fun `GIVEN a fact for a prompt shown for one permission WHEN it is emitted THEN it is properly configured`() {
+ CollectionProcessor.withFactCollection { facts ->
+ emitPermissionDialogDisplayed(Generic("test", "test"))
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.DISPLAY, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals("Generic", facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a fact for a prompt shown for multiple permissions WHEN it is emitted THEN it is properly configured`() {
+ CollectionProcessor.withFactCollection { facts ->
+ emitPermissionsDialogDisplayed(
+ listOf(
+ AppCamera("test", "test"),
+ ContentCrossOriginStorageAccess("test", "test"),
+ AppCamera("test2", "test2"),
+ ),
+ )
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.DISPLAY, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals("AppCamera, ContentCrossOriginStorageAccess", facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a fact for a permission prompt being allowed WHEN it is emitted THEN it is properly configured`() {
+ CollectionProcessor.withFactCollection { facts ->
+ emitPermissionAllowed(ContentAudioCapture("test", "test"))
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CONFIRM, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals("ContentAudioCapture", facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a fact for a multiple permission prompt being allowed WHEN it is emitted THEN it is properly configured`() {
+ CollectionProcessor.withFactCollection { facts ->
+ emitPermissionsAllowed(
+ listOf(
+ ContentAudioCapture("test", "test"),
+ ContentVideoCapture("test", "test"),
+ ContentVideoCapture("test2", "test2"),
+ ),
+ )
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CONFIRM, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals("ContentAudioCapture, ContentVideoCapture", facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a fact for a permission prompt being blocked WHEN it is emitted THEN it is properly configured`() {
+ CollectionProcessor.withFactCollection { facts ->
+ emitPermissionDenied(AppLocationFine("test", "test"))
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CANCEL, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals("AppLocationFine", facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a fact for a multiple permission prompt being blocked WHEN it is emitted THEN it is properly configured`() {
+ CollectionProcessor.withFactCollection { facts ->
+ emitPermissionsDenied(
+ listOf(
+ ContentAudioCapture("test", "test"),
+ ContentVideoCapture("test", "test"),
+ ContentAudioCapture("test2", "test2"),
+ ),
+ )
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CANCEL, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals("ContentAudioCapture, ContentVideoCapture", facts[0].value)
+ }
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt
new file mode 100644
index 0000000000..58672732ee
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsFeatureTest.kt
@@ -0,0 +1,1450 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import android.content.pm.PackageManager.PERMISSION_DENIED
+import android.content.pm.PackageManager.PERMISSION_GRANTED
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentTransaction
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.browser.state.action.ContentAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayAudibleBlockingAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayAudibleChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayInAudibleBlockingAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.AutoPlayInAudibleChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.CameraChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.LocationChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.MediaKeySystemAccesChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.MicrophoneChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.NotificationChangedAction
+import mozilla.components.browser.state.action.ContentAction.UpdatePermissionHighlightsStateAction.PersistentStorageChangedAction
+import mozilla.components.browser.state.state.BrowserState
+import mozilla.components.browser.state.state.ContentState
+import mozilla.components.browser.state.state.SessionState
+import mozilla.components.browser.state.state.TabSessionState
+import mozilla.components.browser.state.state.createTab
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.permission.Permission
+import mozilla.components.concept.engine.permission.Permission.AppAudio
+import mozilla.components.concept.engine.permission.Permission.ContentAudioCapture
+import mozilla.components.concept.engine.permission.Permission.ContentAudioMicrophone
+import mozilla.components.concept.engine.permission.Permission.ContentAutoPlayAudible
+import mozilla.components.concept.engine.permission.Permission.ContentAutoPlayInaudible
+import mozilla.components.concept.engine.permission.Permission.ContentCrossOriginStorageAccess
+import mozilla.components.concept.engine.permission.Permission.ContentGeoLocation
+import mozilla.components.concept.engine.permission.Permission.ContentMediaKeySystemAccess
+import mozilla.components.concept.engine.permission.Permission.ContentNotification
+import mozilla.components.concept.engine.permission.Permission.ContentPersistentStorage
+import mozilla.components.concept.engine.permission.Permission.ContentVideoCamera
+import mozilla.components.concept.engine.permission.Permission.ContentVideoCapture
+import mozilla.components.concept.engine.permission.Permission.Generic
+import mozilla.components.concept.engine.permission.PermissionRequest
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.BLOCKED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.NO_DECISION
+import mozilla.components.concept.engine.permission.SitePermissionsStorage
+import mozilla.components.feature.tabs.TabsUseCases.SelectOrAddUseCase
+import mozilla.components.support.base.Component.FEATURE_SITEPERMISSIONS
+import mozilla.components.support.base.facts.Action
+import mozilla.components.support.base.facts.processor.CollectionProcessor
+import mozilla.components.support.base.feature.OnNeedToRequestPermissions
+import mozilla.components.support.ktx.kotlin.stripDefaultPort
+import mozilla.components.support.test.any
+import mozilla.components.support.test.eq
+import mozilla.components.support.test.ext.joinBlocking
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import mozilla.components.support.test.rule.MainCoroutineRule
+import mozilla.components.support.test.rule.runTestOnMain
+import mozilla.components.support.test.whenever
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.anyString
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.doNothing
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import java.security.InvalidParameterException
+import java.util.UUID
+import mozilla.components.ui.icons.R as iconsR
+
+@RunWith(AndroidJUnit4::class)
+class SitePermissionsFeatureTest {
+ private lateinit var sitePermissionFeature: SitePermissionsFeature
+ private lateinit var mockOnNeedToRequestPermissions: OnNeedToRequestPermissions
+ private lateinit var mockStorage: SitePermissionsStorage
+ private lateinit var mockFragmentManager: FragmentManager
+ private lateinit var mockStore: BrowserStore
+ private lateinit var mockContentState: ContentState
+ private lateinit var mockPermissionRequest: PermissionRequest
+ private lateinit var mockAppPermissionRequest: PermissionRequest
+ private lateinit var mockSitePermissionRules: SitePermissionsRules
+ private lateinit var selectedTab: TabSessionState
+
+ @get:Rule
+ val coroutinesTestRule = MainCoroutineRule()
+ private val scope = coroutinesTestRule.scope
+
+ companion object {
+ const val SESSION_ID = "testSessionId"
+ const val URL = "http://www.example.com"
+ const val PERMISSION_ID = "PERMISSION_ID"
+ }
+
+ @Before
+ fun setup() {
+ mockOnNeedToRequestPermissions = mock()
+ mockStorage = mock()
+ mockFragmentManager = mockFragmentManager()
+ mockContentState = mock()
+ mockPermissionRequest = mock()
+ doReturn(true).`when`(mockPermissionRequest).containsVideoAndAudioSources()
+ mockAppPermissionRequest = mock()
+ mockSitePermissionRules = mock()
+
+ selectedTab = mozilla.components.browser.state.state.createTab(
+ url = "https://www.mozilla.org",
+ id = SESSION_ID,
+ )
+ mockStore = spy(BrowserStore(initialState = BrowserState(tabs = listOf(selectedTab), selectedTabId = selectedTab.id)))
+ sitePermissionFeature = spy(
+ SitePermissionsFeature(
+ context = testContext,
+ sitePermissionsRules = mockSitePermissionRules,
+ onNeedToRequestPermissions = mockOnNeedToRequestPermissions,
+ storage = mockStorage,
+ fragmentManager = mockFragmentManager,
+ onShouldShowRequestPermissionRationale = { false },
+ store = mockStore,
+ sessionId = SESSION_ID,
+ ),
+ )
+ }
+
+ @Test
+ fun `GIVEN a tab load THEN stale permission indicators should be clear up and temporary permissions`() {
+ sitePermissionFeature.start()
+
+ verify(sitePermissionFeature).setupLoadingCollector()
+
+ // when
+ mockStore.dispatch(ContentAction.UpdateLoadingStateAction(SESSION_ID, true)).joinBlocking()
+
+ // then
+ verify(mockStore).dispatch(
+ UpdatePermissionHighlightsStateAction.Reset(SESSION_ID),
+ )
+ verify(mockStorage).clearTemporaryPermissions()
+ }
+
+ @Test
+ fun `GIVEN a tab load after stop is called THEN none stale permission indicators should be clear up`() {
+ sitePermissionFeature.start()
+
+ verify(sitePermissionFeature).setupLoadingCollector()
+
+ sitePermissionFeature.stop()
+
+ // when
+ mockStore.dispatch(ContentAction.UpdateLoadingStateAction(SESSION_ID, true)).joinBlocking()
+
+ verify(mockStorage).clearTemporaryPermissions()
+
+ // then
+ verify(mockStore, never()).dispatch(
+ UpdatePermissionHighlightsStateAction.Reset(SESSION_ID),
+ )
+ }
+
+ @Test
+ fun `GIVEN a sessionId WHEN calling consumePermissionRequest THEN dispatch ConsumePermissionsRequest action with given id`() {
+ // when
+ sitePermissionFeature.consumePermissionRequest(mockPermissionRequest, "sessionIdTest")
+
+ // then
+ verify(mockStore).dispatch(
+ ContentAction.ConsumePermissionsRequest
+ ("sessionIdTest", mockPermissionRequest),
+ )
+ }
+
+ @Test
+ fun `GIVEN no sessionId WHEN calling consumePermissionRequest THEN dispatch ConsumePermissionsRequest action with selected tab`() {
+ // when
+ sitePermissionFeature.consumePermissionRequest(mockPermissionRequest)
+
+ // then
+ verify(mockStore).dispatch(
+ ContentAction.ConsumePermissionsRequest
+ (selectedTab.id, mockPermissionRequest),
+ )
+ }
+
+ @Test
+ fun `GIVEN a sessionId WHEN calling consumeAppPermissionRequest THEN dispatch ConsumeAppPermissionsRequest action with given id`() {
+ // when
+ sitePermissionFeature.consumeAppPermissionRequest(mockAppPermissionRequest, "sessionIdTest")
+
+ // then
+ verify(mockStore).dispatch(
+ ContentAction.ConsumeAppPermissionsRequest
+ ("sessionIdTest", mockAppPermissionRequest),
+ )
+ }
+
+ @Test
+ fun `GIVEN no sessionId WHEN calling consumeAppPermissionRequest THEN dispatch ConsumeAppPermissionsRequest action with selected tab`() {
+ // when
+ sitePermissionFeature.consumeAppPermissionRequest(mockAppPermissionRequest)
+
+ // then
+ verify(mockStore).dispatch(
+ ContentAction.ConsumeAppPermissionsRequest
+ (selectedTab.id, mockAppPermissionRequest),
+ )
+ }
+
+ @Test
+ fun `GIVEN an appPermissionRequest with all granted permissions WHEN onPermissionsResult() THEN grant() and consumeAppPermissionRequest() are called`() {
+ // given
+ doReturn(mockAppPermissionRequest).`when`(sitePermissionFeature)
+ .findRequestedAppPermission(any())
+
+ // when
+ sitePermissionFeature.onPermissionsResult(arrayOf("permission"), arrayOf(PERMISSION_GRANTED).toIntArray())
+
+ // then
+ verify(mockAppPermissionRequest).grant()
+ verify(sitePermissionFeature).consumeAppPermissionRequest(mockAppPermissionRequest)
+ }
+
+ @Test
+ fun `GIVEN an appPermissionRequest with blocked permissions and !onShouldShowRequestPermissionRationale WHEN onPermissionsResult() THEN reject(), storeSitePermissions, consume are called`() {
+ // given
+ doReturn(mockAppPermissionRequest).`when`(sitePermissionFeature)
+ .findRequestedAppPermission(any())
+ doNothing().`when`(sitePermissionFeature)
+ .storeSitePermissions(any(), any(), any(), any())
+
+ // when
+ sitePermissionFeature.onPermissionsResult(
+ arrayOf("permission1", "permission2"),
+ arrayOf(PERMISSION_DENIED, PERMISSION_DENIED).toIntArray(),
+ )
+
+ // then
+ verify(mockAppPermissionRequest).reject()
+ verify(sitePermissionFeature, times(2))
+ .storeSitePermissions(selectedTab.content, mockAppPermissionRequest, BLOCKED)
+ verify(sitePermissionFeature).consumeAppPermissionRequest(mockAppPermissionRequest)
+ }
+
+ @Test
+ fun `GIVEN shouldStore true WHEN onContentPermissionGranted() THEN storeSitePermissions() called`() {
+ // given
+ doNothing().`when`(sitePermissionFeature)
+ .storeSitePermissions(any(), any(), any(), any())
+
+ // when
+ sitePermissionFeature.onContentPermissionGranted(mockPermissionRequest, true)
+
+ // then
+ verify(sitePermissionFeature)
+ .storeSitePermissions(selectedTab.content, mockPermissionRequest, ALLOWED)
+ }
+
+ @Test
+ fun `GIVEN shouldStore false WHEN onContentPermissionGranted() THEN storeSitePermissions() MUST NOT BE called`() {
+ // given
+ doNothing().`when`(sitePermissionFeature)
+ .storeSitePermissions(any(), any(), any(), any())
+
+ // when
+ sitePermissionFeature.onContentPermissionGranted(mockPermissionRequest, false)
+
+ // then
+ verify(sitePermissionFeature, never())
+ .storeSitePermissions(selectedTab.content, mockPermissionRequest, ALLOWED)
+ }
+
+ @Test
+ fun `GIVEN permissionRequest WHEN onPositiveButtonPress() THEN consumePermissionRequest, onContentPermissionGranted are called`() {
+ // given
+ doNothing().`when`(sitePermissionFeature).consumePermissionRequest(any(), any())
+ doNothing().`when`(sitePermissionFeature)
+ .onContentPermissionGranted(mockPermissionRequest, true)
+ doReturn(mockPermissionRequest).`when`(sitePermissionFeature).findRequestedPermission(
+ anyString(),
+ )
+
+ // when
+ sitePermissionFeature.onPositiveButtonPress(PERMISSION_ID, SESSION_ID, true)
+
+ // then
+ verify(sitePermissionFeature)
+ .consumePermissionRequest(mockPermissionRequest, SESSION_ID)
+ verify(sitePermissionFeature)
+ .onContentPermissionGranted(mockPermissionRequest, true)
+ }
+
+ @Test
+ fun `GIVEN a permission prompt WHEN one permission is allowed THEN emit a fact`() {
+ CollectionProcessor.withFactCollection { facts ->
+ doNothing().`when`(sitePermissionFeature).consumePermissionRequest(any(), any())
+ doNothing().`when`(sitePermissionFeature)
+ .onContentPermissionGranted(mockPermissionRequest, true)
+ doReturn(listOf(ContentCrossOriginStorageAccess())).`when`(mockPermissionRequest).permissions
+ doReturn(mockPermissionRequest).`when`(sitePermissionFeature).findRequestedPermission(anyString())
+
+ sitePermissionFeature.onPositiveButtonPress(PERMISSION_ID, SESSION_ID, true)
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CONFIRM, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals(ContentCrossOriginStorageAccess().id, facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a permission prompt WHEN multiple permission are allowed THEN emit a fact`() {
+ CollectionProcessor.withFactCollection { facts ->
+ doReturn(
+ listOf(ContentVideoCapture(), ContentVideoCamera(), ContentAudioMicrophone()),
+ ).`when`(mockPermissionRequest).permissions
+ doReturn(true).`when`(mockPermissionRequest).containsVideoAndAudioSources()
+ doReturn(mockPermissionRequest).`when`(sitePermissionFeature).findRequestedPermission(anyString())
+
+ sitePermissionFeature.onPositiveButtonPress(PERMISSION_ID, SESSION_ID, true)
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CONFIRM, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals(
+ listOf(ContentVideoCapture(), ContentVideoCamera(), ContentAudioMicrophone()).joinToString { it.id!! },
+ facts[0].value,
+ )
+ }
+ }
+
+ @Test
+ fun `GIVEN permissionRequest WHEN onNegativeButtonPress() THEN consumePermissionRequest, onContentPermissionDeny are called`() {
+ // given
+ doNothing().`when`(sitePermissionFeature).consumePermissionRequest(any(), any())
+ doNothing().`when`(sitePermissionFeature)
+ .onContentPermissionDeny(mockPermissionRequest, true)
+ doReturn(mockPermissionRequest).`when`(sitePermissionFeature).findRequestedPermission(
+ anyString(),
+ )
+
+ // when
+ sitePermissionFeature.onNegativeButtonPress(PERMISSION_ID, SESSION_ID, true)
+
+ // then
+ verify(sitePermissionFeature)
+ .consumePermissionRequest(mockPermissionRequest, SESSION_ID)
+ verify(sitePermissionFeature)
+ .onContentPermissionDeny(mockPermissionRequest, true)
+ }
+
+ @Test
+ fun `GIVEN a permission prompt WHEN the permission is denied THEN emit a fact`() {
+ CollectionProcessor.withFactCollection { facts ->
+ doNothing().`when`(sitePermissionFeature).consumePermissionRequest(any(), any())
+ doNothing().`when`(sitePermissionFeature)
+ .onContentPermissionDeny(mockPermissionRequest, true)
+ doReturn(listOf(ContentGeoLocation())).`when`(mockPermissionRequest).permissions
+ doReturn(mockPermissionRequest).`when`(sitePermissionFeature).findRequestedPermission(anyString())
+
+ sitePermissionFeature.onNegativeButtonPress(PERMISSION_ID, SESSION_ID, true)
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CANCEL, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals(ContentGeoLocation().id, facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a permission prompt WHEN multiple permissions are denied THEN emit a fact`() {
+ CollectionProcessor.withFactCollection { facts ->
+ doReturn(
+ listOf(ContentVideoCapture(), ContentVideoCamera(), ContentAudioMicrophone()),
+ ).`when`(mockPermissionRequest).permissions
+ doReturn(true).`when`(mockPermissionRequest).containsVideoAndAudioSources()
+ doReturn(mockPermissionRequest).`when`(sitePermissionFeature).findRequestedPermission(anyString())
+
+ sitePermissionFeature.onNegativeButtonPress(PERMISSION_ID, SESSION_ID, true)
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.CANCEL, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals(
+ listOf(ContentVideoCapture(), ContentVideoCamera(), ContentAudioMicrophone()).joinToString { it.id!! },
+ facts[0].value,
+ )
+ }
+ }
+
+ @Test
+ fun `GIVEN permissionRequest WHEN onDismiss() THEN consumePermissionRequest, onContentPermissionDeny are called`() {
+ // given
+ doNothing().`when`(sitePermissionFeature).consumePermissionRequest(any(), any())
+ doNothing().`when`(sitePermissionFeature)
+ .onContentPermissionDeny(mockPermissionRequest, false)
+ doReturn(mockPermissionRequest).`when`(sitePermissionFeature).findRequestedPermission(
+ anyString(),
+ )
+
+ // when
+ sitePermissionFeature.onDismiss(PERMISSION_ID, SESSION_ID)
+
+ // then
+ verify(sitePermissionFeature)
+ .consumePermissionRequest(mockPermissionRequest, SESSION_ID)
+ verify(sitePermissionFeature)
+ .onContentPermissionDeny(mockPermissionRequest, false)
+ }
+
+ @Test
+ fun `GIVEN permissionRequest WHEN onLearnMorePress() THEN consumePermissionRequest, onContentPermissionDeny are called and SelectOrAddUseCase is used`() {
+ // given
+ val permission: ContentCrossOriginStorageAccess = mock()
+ val permissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(permission))
+ }
+ doNothing().`when`(sitePermissionFeature).consumePermissionRequest(any(), any())
+ doNothing().`when`(sitePermissionFeature)
+ .onContentPermissionDeny(mockPermissionRequest, true)
+ doReturn(permissionRequest).`when`(sitePermissionFeature).findRequestedPermission(
+ anyString(),
+ )
+ doReturn(mock<SelectOrAddUseCase>()).`when`(sitePermissionFeature).selectOrAddUseCase
+
+ // when
+ sitePermissionFeature.onLearnMorePress(PERMISSION_ID, SESSION_ID)
+
+ // then
+ verify(sitePermissionFeature)
+ .consumePermissionRequest(permissionRequest, SESSION_ID)
+ verify(sitePermissionFeature)
+ .onContentPermissionDeny(permissionRequest, false)
+ verify(sitePermissionFeature.selectOrAddUseCase).invoke(
+ url = STORAGE_ACCESS_DOCUMENTATION_URL,
+ private = false,
+ source = SessionState.Source.Internal.TextSelection,
+ )
+ }
+
+ @Test
+ fun `GIVEN a new permissionRequest WHEN storeSitePermissions() THEN save(permissionRequest) is called`() = runTestOnMain {
+ // given
+ val sitePermissions = SitePermissions(origin = "origin", savedAt = 0)
+ doReturn(null).`when`(mockStorage)
+ .findSitePermissionsBy(ArgumentMatchers.anyString(), anyBoolean(), anyBoolean())
+ doNothing().`when`(sitePermissionFeature).updatePermissionToolbarIndicator(
+ any(),
+ any(),
+ anyBoolean(),
+ )
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(Permission.AppAudio(id = "permission")))
+ whenever(uri).thenReturn(URL)
+ }
+ doReturn(sitePermissions).`when`(sitePermissionFeature)
+ .updateSitePermissionsStatus(any(), any(), any())
+
+ // when
+ sitePermissionFeature.storeSitePermissions(
+ mockContentState,
+ mockPermissionRequest,
+ ALLOWED,
+ scope,
+ )
+
+ // then
+ verify(mockStorage).save(sitePermissions, mockPermissionRequest, private = selectedTab.content.private)
+ verify(sitePermissionFeature).updatePermissionToolbarIndicator(
+ mockPermissionRequest,
+ ALLOWED,
+ true,
+ )
+ }
+
+ @Test
+ fun `GIVEN an already saved permissionRequest WHEN storeSitePermissions() THEN update(permissionRequest) is called`() = runTestOnMain {
+ // given
+ val sitePermissions = SitePermissions(origin = "origin", savedAt = 0)
+ doReturn(sitePermissions).`when`(mockStorage)
+ .findSitePermissionsBy(ArgumentMatchers.anyString(), anyBoolean(), anyBoolean())
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(uri).thenReturn(URL)
+ whenever(permissions).thenReturn(listOf(AppAudio(id = "permission")))
+ }
+ doReturn(sitePermissions).`when`(sitePermissionFeature)
+ .updateSitePermissionsStatus(any(), any(), any())
+
+ // when
+ sitePermissionFeature.storeSitePermissions(
+ mockContentState,
+ mockPermissionRequest,
+ ALLOWED,
+ scope,
+ )
+
+ // then
+ verify(mockStorage).update(eq(sitePermissions), anyBoolean())
+ }
+
+ @Test
+ fun `GIVEN a permissionRequest WITH a private tab WHEN storeSitePermissions() THEN save or update MUST NOT BE called`() = runTestOnMain {
+ // then
+ sitePermissionFeature.storeSitePermissions(
+ selectedTab.content.copy(private = true),
+ mockPermissionRequest,
+ ALLOWED,
+ scope,
+ )
+
+ // when
+ verify(mockStorage, never()).save(any(), any(), anyBoolean())
+ verify(mockStorage, never()).update(any(), anyBoolean())
+ }
+
+ @Test
+ fun `GIVEN a permanent permissionRequest WHEN onContentPermissionDeny THEN reject(), storeSitePermissions are called`() {
+ // given
+ doNothing().`when`(mockPermissionRequest).reject()
+ doNothing().`when`(sitePermissionFeature).storeSitePermissions(any(), any(), any(), any())
+
+ // then
+ sitePermissionFeature.onContentPermissionDeny(mockPermissionRequest, true)
+
+ // when
+ verify(mockPermissionRequest).reject()
+ verify(sitePermissionFeature).storeSitePermissions(
+ selectedTab.content,
+ mockPermissionRequest,
+ BLOCKED,
+ )
+ }
+
+ @Test
+ fun `GIVEN a temporary permissionRequest WHEN denying THEN store it on memory`() {
+ doNothing().`when`(mockPermissionRequest).reject()
+ doNothing().`when`(sitePermissionFeature).storeSitePermissions(any(), any(), any(), any())
+
+ sitePermissionFeature.onContentPermissionDeny(mockPermissionRequest, shouldStore = false)
+
+ verify(mockPermissionRequest).reject()
+ verify(mockStorage).saveTemporary(mockPermissionRequest)
+
+ verify(sitePermissionFeature, never()).storeSitePermissions(
+ selectedTab.content,
+ mockPermissionRequest,
+ BLOCKED,
+ )
+ }
+
+ @Test
+ fun `GIVEN a temporary permissionRequest WHEN granting THEN store it on memory`() {
+ doNothing().`when`(mockPermissionRequest).reject()
+ doNothing().`when`(sitePermissionFeature).storeSitePermissions(any(), any(), any(), any())
+
+ sitePermissionFeature.onContentPermissionGranted(mockPermissionRequest, shouldStore = false)
+
+ verify(mockPermissionRequest).grant()
+ verify(mockStorage).saveTemporary(mockPermissionRequest)
+
+ verify(sitePermissionFeature, never()).storeSitePermissions(
+ selectedTab.content,
+ mockPermissionRequest,
+ ALLOWED,
+ )
+ }
+
+ @Test
+ fun `GIVEN a media permissionRequest without all media permissions granted WHEN onContentPermissionRequested() THEN reject, consumePermissionRequest are called `() {
+ // given
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentVideoCamera(id = "permission")))
+ }
+ doNothing().`when`(mockPermissionRequest).reject()
+
+ // when
+ runTestOnMain {
+ sitePermissionFeature.onContentPermissionRequested(mockPermissionRequest, URL)
+ }
+
+ // then
+ verify(mockPermissionRequest).reject()
+ verify(sitePermissionFeature).consumePermissionRequest(mockPermissionRequest)
+ }
+
+ @Test
+ fun `GIVEN sessionId which does not match a selected or custom tab WHEN onContentPermissionRequested() THEN reject, consumePermissionRequest are called `() {
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentVideoCamera(id = "permission")))
+ }
+
+ doNothing().`when`(mockPermissionRequest).reject()
+
+ sitePermissionFeature.sessionId = null
+
+ runTestOnMain {
+ sitePermissionFeature.onContentPermissionRequested(mockPermissionRequest, URL)
+ }
+
+ verify(mockPermissionRequest).reject()
+ verify(sitePermissionFeature).consumePermissionRequest(mockPermissionRequest)
+ }
+
+ @Test
+ fun `GIVEN location permissionRequest and shouldApplyRules is true WHEN onContentPermissionRequested() THEN handleRuledFlow is called`() = runTestOnMain {
+ // given
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentGeoLocation(id = "permission")))
+ }
+ val sitePermissions = SitePermissions(origin = "origin", savedAt = 0)
+ val mockedSitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ doReturn(sitePermissions).`when`(mockStorage).findSitePermissionsBy(URL, private = selectedTab.content.private)
+ doReturn(true).`when`(sitePermissionFeature).shouldApplyRules(any())
+ doReturn(mockedSitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .handleRuledFlow(mockPermissionRequest, URL)
+
+ // when
+ runTestOnMain {
+ sitePermissionFeature.onContentPermissionRequested(
+ mockPermissionRequest,
+ URL,
+ scope,
+ )
+ }
+
+ // then
+ verify(mockStorage).findSitePermissionsBy(URL, private = selectedTab.content.private)
+ verify(sitePermissionFeature).handleRuledFlow(mockPermissionRequest, URL)
+ }
+
+ @Test
+ fun `GIVEN location permissionRequest and shouldApplyRules is false WHEN onContentPermissionRequested() THEN handleNoRuledFlow is called`() = runTestOnMain {
+ // given
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentGeoLocation(id = "permission")))
+ }
+ val sitePermissions = SitePermissions(origin = "origin", savedAt = 0)
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ doReturn(sitePermissions).`when`(mockStorage)
+ .findSitePermissionsBy(URL, private = selectedTab.content.private)
+ doReturn(false).`when`(sitePermissionFeature).shouldApplyRules(any())
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .handleNoRuledFlow(sitePermissions, mockPermissionRequest, URL)
+
+ // when
+ runTestOnMain {
+ sitePermissionFeature.onContentPermissionRequested(
+ mockPermissionRequest,
+ URL,
+ scope,
+ )
+ }
+
+ // then
+ verify(mockStorage).findSitePermissionsBy(URL, private = selectedTab.content.private)
+ verify(sitePermissionFeature).handleNoRuledFlow(sitePermissions, mockPermissionRequest, URL)
+ }
+
+ @Test
+ fun `GIVEN autoplay permissionRequest and shouldApplyRules is false WHEN onContentPermissionRequested() THEN handleNoRuledFlow is called`() = runTestOnMain {
+ // given
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentAutoPlayInaudible(id = "permission")))
+ }
+ val sitePermissions = SitePermissions(origin = "origin", savedAt = 0)
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+
+ doReturn(sitePermissions).`when`(mockStorage).findSitePermissionsBy(URL, private = selectedTab.content.private)
+ doReturn(false).`when`(sitePermissionFeature).shouldApplyRules(any())
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .handleNoRuledFlow(sitePermissions, mockPermissionRequest, URL)
+
+ // when
+ runTestOnMain {
+ sitePermissionFeature.onContentPermissionRequested(
+ mockPermissionRequest,
+ URL,
+ scope,
+ )
+ }
+
+ // then
+ verify(mockStorage).findSitePermissionsBy(URL, private = selectedTab.content.private)
+ verify(sitePermissionFeature).handleNoRuledFlow(sitePermissions, mockPermissionRequest, URL)
+ }
+
+ @Test
+ fun `GIVEN shouldShowPrompt with isForAutoplay false AND null permissionFromStorage THEN return true`() = runTestOnMain {
+ // given
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(Permission.ContentGeoLocation(id = "permission")))
+ }
+
+ // when
+ val shouldShowPrompt = sitePermissionFeature.shouldShowPrompt(mockPermissionRequest, null)
+
+ // then
+ assertTrue(shouldShowPrompt)
+ }
+
+ @Test
+ fun `GIVEN shouldShowPrompt with isForAutoplay true THEN return false`() {
+ // given
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(Permission.ContentAutoPlayInaudible(id = "permission")))
+ }
+
+ // when
+ val shouldShowPrompt = sitePermissionFeature.shouldShowPrompt(mockPermissionRequest, mock())
+
+ // then
+ assertFalse(shouldShowPrompt)
+ }
+
+ @Test
+ fun `GIVEN shouldShowPrompt true WHEN handleNoRuledFlow THEN createPrompt is called`() {
+ // given
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ val sitePermissions = SitePermissions(origin = "origin", savedAt = 0)
+ doReturn(true).`when`(sitePermissionFeature)
+ .shouldShowPrompt(mockPermissionRequest, sitePermissions)
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .createPrompt(any(), any())
+
+ // when
+ sitePermissionFeature.handleNoRuledFlow(sitePermissions, mockPermissionRequest, URL)
+
+ // then
+ verify(sitePermissionFeature).createPrompt(mockPermissionRequest, URL)
+ }
+
+ @Test
+ fun `GIVEN shouldShowPrompt false and permissionFromStorage not granted WHEN handleNoRuledFlow THEN reject, consumePermissionRequest are called `() {
+ // given
+ doReturn(false).`when`(sitePermissionFeature).shouldShowPrompt(mockPermissionRequest, null)
+ doNothing().`when`(sitePermissionFeature).updatePermissionToolbarIndicator(mockPermissionRequest, BLOCKED)
+
+ // when
+ sitePermissionFeature.handleNoRuledFlow(null, mockPermissionRequest, URL)
+
+ // then
+ verify(mockPermissionRequest).reject()
+ verify(sitePermissionFeature).consumePermissionRequest(mockPermissionRequest)
+ verify(sitePermissionFeature).updatePermissionToolbarIndicator(
+ mockPermissionRequest,
+ BLOCKED,
+ )
+ }
+
+ @Test
+ fun `GIVEN AutoplayAudible request WHEN calling updatePermissionToolbarIndicator THEN dispatch AutoPlayAudibleBlockingAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentAutoPlayAudible(id = "permission")))
+ }
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED)
+
+ verify(mockStore).dispatch(AutoPlayAudibleBlockingAction(tab1.id, true))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED)
+
+ verify(mockStore).dispatch(AutoPlayAudibleBlockingAction(tab1.id, false))
+ }
+
+ @Test
+ fun `GIVEN AutoplayInaudible request WHEN calling updatePermissionToolbarIndicator THEN dispatch AutoPlayInAudibleBlockingAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentAutoPlayInaudible(id = "permission")))
+ }
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED)
+
+ verify(mockStore).dispatch(AutoPlayInAudibleBlockingAction(tab1.id, true))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED)
+
+ verify(mockStore).dispatch(AutoPlayInAudibleBlockingAction(tab1.id, false))
+ }
+
+ @Test
+ fun `GIVEN notification request WHEN calling updatePermissionToolbarIndicator THEN dispatch NotificationChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentNotification(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.Action.BLOCKED).`when`(mockSitePermissionRules).notification
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, false)
+
+ verify(mockStore, never()).dispatch(any<NotificationChangedAction>())
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(NotificationChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(NotificationChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN camera request WHEN calling updatePermissionToolbarIndicator THEN dispatch CameraChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentVideoCamera(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.Action.BLOCKED).`when`(mockSitePermissionRules).camera
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, false)
+
+ verify(mockStore, never()).dispatch(any<CameraChangedAction>())
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(CameraChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(CameraChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN location request WHEN calling updatePermissionToolbarIndicator THEN dispatch CameraChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentGeoLocation(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.Action.BLOCKED).`when`(mockSitePermissionRules).location
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, false)
+
+ verify(mockStore, never()).dispatch(any<LocationChangedAction>())
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(LocationChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(LocationChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN microphone request WHEN calling updatePermissionToolbarIndicator THEN dispatch MicrophoneChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentAudioCapture(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.Action.BLOCKED).`when`(mockSitePermissionRules).microphone
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, false)
+
+ verify(mockStore, never()).dispatch(any<MicrophoneChangedAction>())
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(MicrophoneChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(MicrophoneChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN persistentStorage request WHEN calling updatePermissionToolbarIndicator THEN dispatch PersistentStorageChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentPersistentStorage(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.Action.BLOCKED).`when`(mockSitePermissionRules).persistentStorage
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, false)
+
+ verify(mockStore, never()).dispatch(any<PersistentStorageChangedAction>())
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(PersistentStorageChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(PersistentStorageChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN mediaKeySystemAccess request WHEN calling updatePermissionToolbarIndicator THEN dispatch MediaKeySystemAccesChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentMediaKeySystemAccess(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.Action.BLOCKED).`when`(mockSitePermissionRules).mediaKeySystemAccess
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, false)
+
+ verify(mockStore, never()).dispatch(any<MediaKeySystemAccesChangedAction>())
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(MediaKeySystemAccesChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(MediaKeySystemAccesChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN autoplayAudible request WHEN calling updatePermissionToolbarIndicator THEN dispatch AutoPlayAudibleChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentAutoPlayAudible(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.AutoplayAction.BLOCKED).`when`(mockSitePermissionRules).autoplayAudible
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(AutoPlayAudibleChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(AutoPlayAudibleChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN autoplayInaudible request WHEN calling updatePermissionToolbarIndicator THEN dispatch AutoPlayInAudibleChangedAction`() {
+ val tab1 = createTab("https://www.mozilla.org", id = "1")
+ val request: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentAutoPlayInaudible(id = "permission")))
+ }
+
+ doReturn(tab1).`when`(sitePermissionFeature).getCurrentTabState()
+ doReturn(SitePermissionsRules.AutoplayAction.BLOCKED).`when`(mockSitePermissionRules).autoplayInaudible
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, BLOCKED, true)
+
+ verify(mockStore).dispatch(AutoPlayInAudibleChangedAction(tab1.id, false))
+
+ sitePermissionFeature.updatePermissionToolbarIndicator(request, ALLOWED, true)
+
+ verify(mockStore).dispatch(AutoPlayInAudibleChangedAction(tab1.id, true))
+ }
+
+ @Test
+ fun `GIVEN shouldShowPrompt false and permissionFromStorage granted WHEN handleNoRuledFlow THEN grant, consumePermissionRequest are called `() {
+ // given
+ val sitePermissions = SitePermissions(origin = "origin", savedAt = 0, location = ALLOWED)
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentGeoLocation(id = "permission")))
+ }
+ doNothing().`when`(sitePermissionFeature)
+ .updatePermissionToolbarIndicator(mockPermissionRequest, ALLOWED, true)
+
+ doReturn(false).`when`(sitePermissionFeature)
+ .shouldShowPrompt(mockPermissionRequest, sitePermissions)
+
+ // when
+ sitePermissionFeature.handleNoRuledFlow(sitePermissions, mockPermissionRequest, URL)
+
+ // then
+ verify(mockPermissionRequest, atLeastOnce()).grant()
+ verify(sitePermissionFeature).consumePermissionRequest(mockPermissionRequest)
+ verify(sitePermissionFeature).updatePermissionToolbarIndicator(mockPermissionRequest, ALLOWED, true)
+ }
+
+ @Test
+ fun `GIVEN permissionRequest with isForAutoplay true and BLOCKED WHEN handleRuledFlow THEN reject, consumePermissionRequest are called`() {
+ // given
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentAutoPlayAudible(id = "permission")))
+ }
+ doNothing().`when`(sitePermissionFeature)
+ .updatePermissionToolbarIndicator(mockPermissionRequest, BLOCKED)
+ doReturn(mockSitePermissionRules).`when`(sitePermissionFeature).sitePermissionsRules
+ doReturn(SitePermissionsRules.Action.BLOCKED).`when`(mockSitePermissionRules)
+ .getActionFrom(mockPermissionRequest)
+
+ // when
+ sitePermissionFeature.handleRuledFlow(mockPermissionRequest, URL)
+
+ // then
+ verify(mockPermissionRequest).reject()
+ verify(sitePermissionFeature).consumePermissionRequest(mockPermissionRequest)
+ verify(sitePermissionFeature).updatePermissionToolbarIndicator(
+ mockPermissionRequest,
+ BLOCKED,
+ )
+ }
+
+ @Test
+ fun `GIVEN permissionRequest with isForAutoplay false and ASK_TO_ALLOW WHEN handleRuledFlow THEN createPrompt is called`() {
+ // given
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentGeoLocation(id = "permission")))
+ }
+ doReturn(mockSitePermissionRules).`when`(sitePermissionFeature).sitePermissionsRules
+ doReturn(SitePermissionsRules.Action.ASK_TO_ALLOW).`when`(mockSitePermissionRules)
+ .getActionFrom(mockPermissionRequest)
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .createPrompt(mockPermissionRequest, URL)
+
+ // when
+ sitePermissionFeature.handleRuledFlow(mockPermissionRequest, URL)
+
+ // then
+ verify(sitePermissionFeature).createPrompt(mockPermissionRequest, URL)
+ }
+
+ @Test
+ fun `GIVEN permissionRequest and containsVideoAndAudioSources false WHEN createPrompt THEN handlingSingleContentPermissions is called`() {
+ // given
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentGeoLocation(id = "permission")))
+ }
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .handlingSingleContentPermissions(any(), any(), any())
+
+ // when
+ sitePermissionFeature.createPrompt(mockPermissionRequest, URL)
+
+ // then
+ verify(sitePermissionFeature).handlingSingleContentPermissions(
+ mockPermissionRequest,
+ ContentGeoLocation(id = "permission"),
+ URL,
+ )
+ }
+
+ @Test
+ fun `GIVEN a ContentStorageAccess request WHEN handlingSingleContentPermissions is called THEN create a specific prompt`() {
+ // given
+ val host = "https://mozilla.org"
+ val permission = ContentCrossOriginStorageAccess(id = "permission")
+ val permissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(permission))
+ whenever(id).thenReturn("id")
+ }
+
+ // when
+ sitePermissionFeature.handlingSingleContentPermissions(permissionRequest, permission, host)
+
+ // then
+ verify(sitePermissionFeature).createContentCrossOriginStorageAccessPermissionPrompt(
+ context = testContext,
+ host,
+ permissionRequest,
+ false,
+ true,
+ )
+ }
+
+ @Test
+ fun `GIVEN a ContentStorageAccess request WHEN createContentStorageAccessPermissionPrompt is called THEN create a specific SitePermissionsDialogFragment`() {
+ // given
+ val host = "https://mozilla.org"
+ val permission = ContentCrossOriginStorageAccess(id = "permission")
+ val permissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(permission))
+ whenever(id).thenReturn("id")
+ }
+
+ // when
+ val dialog = sitePermissionFeature.createContentCrossOriginStorageAccessPermissionPrompt(
+ testContext,
+ host,
+ permissionRequest,
+ false,
+ true,
+ )
+
+ // then
+ assertEquals(SESSION_ID, dialog.sessionId)
+ assertEquals(
+ testContext.getString(
+ R.string.mozac_feature_sitepermissions_storage_access_title,
+ host.stripDefaultPort(),
+ selectedTab.content.url.stripDefaultPort(),
+ ),
+ dialog.title,
+ )
+ assertEquals(iconsR.drawable.mozac_ic_cookies_24, dialog.icon)
+ assertEquals(permissionRequest.id, dialog.permissionRequestId)
+ assertEquals(sitePermissionFeature, dialog.feature)
+ assertEquals(false, dialog.shouldShowDoNotAskAgainCheckBox)
+ assertEquals(true, dialog.shouldPreselectDoNotAskAgainCheckBox)
+ assertEquals(false, dialog.isNotificationRequest)
+ assertEquals(
+ testContext.getString(
+ R.string.mozac_feature_sitepermissions_storage_access_message,
+ host.stripDefaultPort(),
+ ),
+ dialog.message,
+ )
+ assertEquals(
+ testContext.getString(R.string.mozac_feature_sitepermissions_storage_access_not_allow),
+ dialog.negativeButtonText,
+ )
+ assertEquals(true, dialog.shouldShowLearnMoreLink)
+ }
+
+ @Test
+ fun `GIVEN permissionRequest and containsVideoAndAudioSources true WHEN createPrompt THEN createSinglePermissionPrompt is called`() {
+ // given
+ val permissionRequest: PermissionRequest = object : PermissionRequest {
+ override val uri: String?
+ get() = "http://www.mozilla.org"
+ override val id: String
+ get() = PERMISSION_ID
+
+ override val permissions: List<Permission>
+ get() = listOf(
+ ContentVideoCapture("", "back camera"),
+ ContentVideoCamera("", "front camera"),
+ ContentAudioMicrophone(),
+ )
+
+ override fun grant(permissions: List<Permission>) {
+ }
+
+ override fun containsVideoAndAudioSources() = true
+
+ override fun reject() = Unit
+ }
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .createSinglePermissionPrompt(
+ any(),
+ ArgumentMatchers.anyString(),
+ any(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyBoolean(),
+ )
+
+ // when
+ sitePermissionFeature.createPrompt(permissionRequest, URL)
+
+ // then
+ verify(sitePermissionFeature).createSinglePermissionPrompt(
+ any(),
+ ArgumentMatchers.anyString(),
+ any(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyBoolean(),
+ )
+ }
+
+ @Test
+ fun `GIVEN a request for one permission WHEN a prompt is created THEN emit a fact`() {
+ CollectionProcessor.withFactCollection { facts ->
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ val mockPermissionRequest: PermissionRequest = mock {
+ whenever(permissions).thenReturn(listOf(ContentGeoLocation(id = "permission")))
+ }
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .handlingSingleContentPermissions(any(), any(), any())
+
+ sitePermissionFeature.createPrompt(mockPermissionRequest, URL)
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.DISPLAY, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals("ContentGeoLocation", facts[0].value)
+ }
+ }
+
+ @Test
+ fun `GIVEN a request for a permission with video and audio sources WHEN a prompt is created THEN emit a fact`() {
+ CollectionProcessor.withFactCollection { facts ->
+ val permissionRequest: PermissionRequest = object : PermissionRequest {
+ override val uri = "http://www.mozilla.org"
+ override val id = PERMISSION_ID
+
+ override val permissions: List<Permission>
+ get() = listOf(ContentVideoCapture(), ContentVideoCamera(), ContentAudioMicrophone())
+
+ override fun grant(permissions: List<Permission>) {}
+
+ override fun containsVideoAndAudioSources() = true
+
+ override fun reject() = Unit
+ }
+ val sitePermissionsDialogFragment = SitePermissionsDialogFragment()
+ doReturn(sitePermissionsDialogFragment).`when`(sitePermissionFeature)
+ .createSinglePermissionPrompt(
+ any(),
+ ArgumentMatchers.anyString(),
+ any(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyBoolean(),
+ )
+
+ sitePermissionFeature.createPrompt(permissionRequest, URL)
+
+ assertEquals(1, facts.size)
+ assertEquals(FEATURE_SITEPERMISSIONS, facts[0].component)
+ assertEquals(Action.DISPLAY, facts[0].action)
+ assertEquals(SitePermissionsFacts.Items.PERMISSIONS, facts[0].item)
+ assertEquals(permissionRequest.permissions.joinToString { it.id!! }, facts[0].value)
+ }
+ }
+
+ @Test
+ fun `is SitePermission granted in the storage`() = runTestOnMain {
+ val sitePermissionsList = listOf(
+ ContentGeoLocation(),
+ ContentNotification(),
+ ContentAudioCapture(),
+ ContentAudioMicrophone(),
+ ContentVideoCamera(),
+ ContentVideoCapture(),
+ ContentPersistentStorage(),
+ ContentAutoPlayAudible(),
+ ContentAutoPlayInaudible(),
+ ContentMediaKeySystemAccess(),
+ )
+
+ sitePermissionsList.forEach { permission ->
+ val request: PermissionRequest = mock()
+ val sitePermissionFromStorage: SitePermissions = mock()
+
+ doReturn(listOf(permission)).`when`(request).permissions
+ doReturn(sitePermissionFromStorage).`when`(mockStorage)
+ .findSitePermissionsBy(anyString(), anyBoolean(), anyBoolean())
+ doReturn(ALLOWED).`when`(sitePermissionFromStorage).location
+ doReturn(ALLOWED).`when`(sitePermissionFromStorage).notification
+ doReturn(ALLOWED).`when`(sitePermissionFromStorage).camera
+ doReturn(ALLOWED).`when`(sitePermissionFromStorage).microphone
+ doReturn(ALLOWED).`when`(sitePermissionFromStorage).localStorage
+ doReturn(ALLOWED).`when`(sitePermissionFromStorage).crossOriginStorageAccess
+ doReturn(ALLOWED).`when`(sitePermissionFromStorage).mediaKeySystemAccess
+ doReturn(AutoplayStatus.ALLOWED).`when`(sitePermissionFromStorage).autoplayAudible
+ doReturn(AutoplayStatus.ALLOWED).`when`(sitePermissionFromStorage).autoplayInaudible
+
+ val isAllowed = sitePermissionFromStorage.isGranted(request)
+ assertTrue(isAllowed)
+ }
+ }
+
+ @Test
+ fun `is SitePermission blocked in the storage`() = runTestOnMain {
+ val sitePermissionsList = listOf(
+ ContentGeoLocation(),
+ ContentNotification(),
+ ContentAudioCapture(),
+ ContentAudioMicrophone(),
+ ContentVideoCamera(),
+ ContentVideoCapture(),
+ ContentCrossOriginStorageAccess(),
+ Generic(),
+ )
+
+ var exceptionThrown = false
+ sitePermissionsList.forEach { permission ->
+ val request: PermissionRequest = mock()
+ val sitePermissionFromStorage: SitePermissions = mock()
+
+ doReturn(listOf(permission)).`when`(request).permissions
+ doReturn(sitePermissionFromStorage).`when`(mockStorage)
+ .findSitePermissionsBy(anyString(), anyBoolean(), anyBoolean())
+ doReturn(BLOCKED).`when`(sitePermissionFromStorage).location
+ doReturn(BLOCKED).`when`(sitePermissionFromStorage).notification
+ doReturn(BLOCKED).`when`(sitePermissionFromStorage).camera
+ doReturn(BLOCKED).`when`(sitePermissionFromStorage).microphone
+ doReturn(BLOCKED).`when`(sitePermissionFromStorage).crossOriginStorageAccess
+
+ try {
+ val isAllowed = sitePermissionFromStorage.isGranted(request)
+ assertFalse(isAllowed)
+ } catch (e: InvalidParameterException) {
+ exceptionThrown = true
+ }
+ }
+ assertTrue(exceptionThrown)
+ }
+
+ @Test
+ fun `feature will re-attach to already existing fragment`() {
+ doReturn(false).`when`(sitePermissionFeature).noPermissionRequests(any())
+
+ val fragment: SitePermissionsDialogFragment = mock()
+ doReturn(selectedTab.id).`when`(fragment).sessionId
+ doReturn(fragment).`when`(mockFragmentManager).findFragmentByTag(any())
+
+ sitePermissionFeature.start()
+ verify(fragment).feature = sitePermissionFeature
+ }
+
+ @Test
+ fun `already existing fragment will be removed if session has none permissions request set anymore`() {
+ // given
+ val session = selectedTab
+ val fragment: SitePermissionsDialogFragment = mock()
+ doReturn(session.id).`when`(fragment).sessionId
+ val transaction: FragmentTransaction = mock()
+ doReturn(fragment).`when`(mockFragmentManager).findFragmentByTag(any())
+ doReturn(transaction).`when`(mockFragmentManager).beginTransaction()
+ doReturn(transaction).`when`(transaction).remove(fragment)
+ doReturn(mockContentState).`when`(sitePermissionFeature)
+ .getCurrentContentState()
+ doNothing().`when`(sitePermissionFeature).setupPermissionRequestsCollector()
+ doNothing().`when`(sitePermissionFeature).setupAppPermissionRequestsCollector()
+
+ // when
+ sitePermissionFeature.start()
+
+ // then
+ verify(mockFragmentManager).beginTransaction()
+ verify(transaction).remove(fragment)
+ }
+
+ @Test
+ fun `already existing fragment will be removed if session does not exist anymore`() {
+ val fragment: SitePermissionsDialogFragment = mock()
+ doReturn(UUID.randomUUID().toString()).`when`(fragment).sessionId
+ doReturn(mockContentState).`when`(sitePermissionFeature)
+ .getCurrentContentState()
+ doNothing().`when`(sitePermissionFeature).setupPermissionRequestsCollector()
+ doNothing().`when`(sitePermissionFeature).setupAppPermissionRequestsCollector()
+
+ val transaction: FragmentTransaction = mock()
+
+ doReturn(fragment).`when`(mockFragmentManager).findFragmentByTag(any())
+ doReturn(transaction).`when`(mockFragmentManager).beginTransaction()
+ doReturn(transaction).`when`(transaction).remove(fragment)
+
+ sitePermissionFeature.start()
+ verify(mockFragmentManager).beginTransaction()
+ verify(transaction).remove(fragment)
+ }
+
+ @Test
+ fun `getInitialSitePermissions - WHEN sitePermissionsRules is present the function MUST use the sitePermissionsRules values to create a SitePermissions object`() = runTestOnMain {
+ val rules = SitePermissionsRules(
+ location = SitePermissionsRules.Action.BLOCKED,
+ camera = SitePermissionsRules.Action.ASK_TO_ALLOW,
+ notification = SitePermissionsRules.Action.ASK_TO_ALLOW,
+ microphone = SitePermissionsRules.Action.BLOCKED,
+ autoplayAudible = SitePermissionsRules.AutoplayAction.BLOCKED,
+ autoplayInaudible = SitePermissionsRules.AutoplayAction.ALLOWED,
+ persistentStorage = SitePermissionsRules.Action.BLOCKED,
+ crossOriginStorageAccess = SitePermissionsRules.Action.ALLOWED,
+ mediaKeySystemAccess = SitePermissionsRules.Action.ASK_TO_ALLOW,
+ )
+
+ sitePermissionFeature.sitePermissionsRules = rules
+
+ val sitePermissions = sitePermissionFeature.getInitialSitePermissions(URL)
+
+ assertEquals(URL, sitePermissions.origin)
+ assertEquals(BLOCKED, sitePermissions.location)
+ assertEquals(NO_DECISION, sitePermissions.camera)
+ assertEquals(NO_DECISION, sitePermissions.notification)
+ assertEquals(BLOCKED, sitePermissions.microphone)
+ assertEquals(BLOCKED, sitePermissions.autoplayAudible.toStatus())
+ assertEquals(ALLOWED, sitePermissions.autoplayInaudible.toStatus())
+ assertEquals(BLOCKED, sitePermissions.localStorage)
+ assertEquals(ALLOWED, sitePermissions.crossOriginStorageAccess)
+ assertEquals(NO_DECISION, sitePermissions.mediaKeySystemAccess)
+ }
+
+ @Test
+ fun `any media request must be rejected WHEN system permissions are not granted first`() = runTestOnMain {
+ val permissions = listOf(
+ ContentVideoCapture("", "back camera"),
+ ContentVideoCamera("", "front camera"),
+ ContentAudioCapture(),
+ ContentAudioMicrophone(),
+ )
+
+ permissions.forEach { permission ->
+ var grantWasCalled = false
+
+ val permissionRequest: PermissionRequest = object : PermissionRequest {
+ override val uri: String?
+ get() = "http://www.mozilla.org"
+ override val id: String
+ get() = PERMISSION_ID
+ override val permissions: List<Permission>
+ get() = listOf(permission)
+
+ override fun grant(permissions: List<Permission>) {
+ grantWasCalled = true
+ }
+
+ override fun reject() = Unit
+ }
+
+ mockStorage = mock()
+
+ val prompt = sitePermissionFeature
+ .onContentPermissionRequested(permissionRequest, URL)
+ assertNull(prompt)
+ assertFalse(grantWasCalled)
+ }
+
+ Unit
+ }
+
+ private fun mockFragmentManager(): FragmentManager {
+ val fragmentManager: FragmentManager = mock()
+ val transaction: FragmentTransaction = mock()
+ doReturn(transaction).`when`(fragmentManager).beginTransaction()
+ return fragmentManager
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt
new file mode 100644
index 0000000000..8ccd9a8a7e
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsRulesTest.kt
@@ -0,0 +1,199 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.permission.Permission
+import mozilla.components.concept.engine.permission.Permission.ContentAudioCapture
+import mozilla.components.concept.engine.permission.Permission.ContentGeoLocation
+import mozilla.components.concept.engine.permission.Permission.ContentNotification
+import mozilla.components.concept.engine.permission.Permission.ContentVideoCapture
+import mozilla.components.concept.engine.permission.Permission.Generic
+import mozilla.components.concept.engine.permission.PermissionRequest
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status
+import mozilla.components.concept.engine.permission.SitePermissionsStorage
+import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ALLOWED
+import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ASK_TO_ALLOW
+import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.BLOCKED
+import mozilla.components.feature.sitepermissions.SitePermissionsRules.AutoplayAction
+import mozilla.components.support.base.feature.OnNeedToRequestPermissions
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.robolectric.testContext
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.doReturn
+
+@RunWith(AndroidJUnit4::class)
+class SitePermissionsRulesTest {
+
+ private lateinit var anchorView: View
+ private lateinit var rules: SitePermissionsFeature
+ private lateinit var mockOnNeedToRequestPermissions: OnNeedToRequestPermissions
+ private lateinit var mockStorage: SitePermissionsStorage
+
+ @Before
+ fun setup() {
+ anchorView = View(testContext)
+ mockOnNeedToRequestPermissions = mock()
+ mockStorage = mock()
+
+ rules = SitePermissionsFeature(
+ context = testContext,
+ onNeedToRequestPermissions = mockOnNeedToRequestPermissions,
+ storage = mockStorage,
+ fragmentManager = mock(),
+ onShouldShowRequestPermissionRationale = mock(),
+ store = BrowserStore(),
+ )
+ }
+
+ @Test
+ fun `getActionFrom must return the right action per permission`() {
+ val rules = SitePermissionsRules(
+ camera = ASK_TO_ALLOW,
+ location = BLOCKED,
+ notification = ASK_TO_ALLOW,
+ microphone = BLOCKED,
+ autoplayAudible = AutoplayAction.BLOCKED,
+ autoplayInaudible = AutoplayAction.ALLOWED,
+ persistentStorage = BLOCKED,
+ crossOriginStorageAccess = ALLOWED,
+ mediaKeySystemAccess = ASK_TO_ALLOW,
+ )
+
+ val mockRequest: PermissionRequest = mock()
+
+ doReturn(listOf(ContentGeoLocation())).`when`(mockRequest).permissions
+ var action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.location)
+
+ doReturn(listOf(ContentNotification())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.notification)
+
+ doReturn(listOf(ContentAudioCapture())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.microphone)
+
+ doReturn(listOf(ContentVideoCapture())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.camera)
+
+ doReturn(listOf(Permission.ContentAutoPlayAudible())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.autoplayAudible.toAction())
+
+ doReturn(listOf(Permission.ContentAutoPlayInaudible())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.autoplayInaudible.toAction())
+
+ doReturn(listOf(Generic("", ""))).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.camera)
+
+ doReturn(listOf(Permission.ContentPersistentStorage())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.persistentStorage)
+
+ doReturn(listOf(Permission.ContentCrossOriginStorageAccess())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.crossOriginStorageAccess)
+
+ doReturn(listOf(Permission.ContentMediaKeySystemAccess())).`when`(mockRequest).permissions
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, rules.mediaKeySystemAccess)
+ }
+
+ @Test
+ fun `getActionFrom must return the right action for a Camera + Microphone permission`() {
+ var rules = SitePermissionsRules(
+ camera = ASK_TO_ALLOW,
+ location = BLOCKED,
+ crossOriginStorageAccess = ALLOWED,
+ persistentStorage = BLOCKED,
+ notification = ASK_TO_ALLOW,
+ microphone = BLOCKED,
+ autoplayInaudible = AutoplayAction.ALLOWED,
+ autoplayAudible = AutoplayAction.BLOCKED,
+ mediaKeySystemAccess = ASK_TO_ALLOW,
+ )
+
+ val mockRequest: PermissionRequest = mock()
+ doReturn(true).`when`(mockRequest).containsVideoAndAudioSources()
+
+ var action = rules.getActionFrom(mockRequest)
+ assertEquals(action, BLOCKED)
+
+ rules = SitePermissionsRules(
+ camera = ASK_TO_ALLOW,
+ location = BLOCKED,
+ crossOriginStorageAccess = ALLOWED,
+ notification = ASK_TO_ALLOW,
+ microphone = ASK_TO_ALLOW,
+ autoplayInaudible = AutoplayAction.ALLOWED,
+ autoplayAudible = AutoplayAction.BLOCKED,
+ persistentStorage = BLOCKED,
+ mediaKeySystemAccess = ASK_TO_ALLOW,
+ )
+
+ action = rules.getActionFrom(mockRequest)
+ assertEquals(action, ASK_TO_ALLOW)
+ }
+
+ @Test
+ fun `toSitePermissions - converts a SitePermissionsRules to SitePermissions`() {
+ val expectedSitePermission = SitePermissions(
+ origin = "origin",
+ camera = Status.NO_DECISION,
+ location = Status.BLOCKED,
+ localStorage = Status.BLOCKED,
+ crossOriginStorageAccess = Status.ALLOWED,
+ notification = Status.NO_DECISION,
+ microphone = Status.BLOCKED,
+ autoplayInaudible = AutoplayStatus.ALLOWED,
+ autoplayAudible = AutoplayStatus.BLOCKED,
+ mediaKeySystemAccess = Status.BLOCKED,
+ savedAt = 1L,
+ )
+
+ val rules = SitePermissionsRules(
+ camera = ASK_TO_ALLOW,
+ location = BLOCKED,
+ notification = ASK_TO_ALLOW,
+ microphone = BLOCKED,
+ autoplayInaudible = AutoplayAction.ALLOWED,
+ autoplayAudible = AutoplayAction.BLOCKED,
+ persistentStorage = BLOCKED,
+ crossOriginStorageAccess = ALLOWED,
+ mediaKeySystemAccess = BLOCKED,
+ )
+
+ val convertedSitePermissions = rules.toSitePermissions(origin = "origin", savedAt = 1L)
+
+ assertEquals(expectedSitePermission.origin, convertedSitePermissions.origin)
+ assertEquals(expectedSitePermission.camera, convertedSitePermissions.camera)
+ assertEquals(expectedSitePermission.location, convertedSitePermissions.location)
+ assertEquals(expectedSitePermission.notification, convertedSitePermissions.notification)
+ assertEquals(expectedSitePermission.microphone, convertedSitePermissions.microphone)
+ assertEquals(expectedSitePermission.autoplayInaudible, convertedSitePermissions.autoplayInaudible)
+ assertEquals(expectedSitePermission.autoplayAudible, convertedSitePermissions.autoplayAudible)
+ assertEquals(expectedSitePermission.localStorage, convertedSitePermissions.localStorage)
+ assertEquals(expectedSitePermission.crossOriginStorageAccess, convertedSitePermissions.crossOriginStorageAccess)
+ assertEquals(expectedSitePermission.mediaKeySystemAccess, convertedSitePermissions.mediaKeySystemAccess)
+ assertEquals(expectedSitePermission.savedAt, convertedSitePermissions.savedAt)
+ }
+
+ @Test
+ fun `AutoplayAction - toAutoplayStatus`() {
+ assertEquals(AutoplayStatus.ALLOWED, AutoplayAction.ALLOWED.toAutoplayStatus())
+ assertEquals(AutoplayStatus.BLOCKED, AutoplayAction.BLOCKED.toAutoplayStatus())
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsTest.kt
new file mode 100644
index 0000000000..20ef50cf53
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/SitePermissionsTest.kt
@@ -0,0 +1,88 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions
+
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.BLOCKED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.NO_DECISION
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.AUTOPLAY_AUDIBLE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.AUTOPLAY_INAUDIBLE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.BLUETOOTH
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.CAMERA
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.LOCAL_STORAGE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.LOCATION
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.MICROPHONE
+import mozilla.components.concept.engine.permission.SitePermissionsStorage.Permission.NOTIFICATION
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class SitePermissionsTest {
+ @Test
+ fun `Tests get() against direct property access`() {
+ var sitePermissions = SitePermissions(origin = "mozilla.dev", savedAt = 0)
+
+ assertEquals(NO_DECISION, sitePermissions[NOTIFICATION])
+ assertEquals(NO_DECISION, sitePermissions[LOCATION])
+ assertEquals(NO_DECISION, sitePermissions[LOCAL_STORAGE])
+ assertEquals(NO_DECISION, sitePermissions[MICROPHONE])
+ assertEquals(NO_DECISION, sitePermissions[BLUETOOTH])
+ assertEquals(NO_DECISION, sitePermissions[CAMERA])
+ assertEquals(BLOCKED, sitePermissions[AUTOPLAY_AUDIBLE])
+ assertEquals(ALLOWED, sitePermissions[AUTOPLAY_INAUDIBLE])
+
+ sitePermissions = sitePermissions.copy(
+ location = ALLOWED,
+ notification = BLOCKED,
+ microphone = NO_DECISION,
+ autoplayAudible = AutoplayStatus.ALLOWED,
+ autoplayInaudible = AutoplayStatus.BLOCKED,
+ )
+
+ assertEquals(BLOCKED, sitePermissions[NOTIFICATION])
+ assertEquals(ALLOWED, sitePermissions[LOCATION])
+ assertEquals(NO_DECISION, sitePermissions[MICROPHONE])
+ assertEquals(NO_DECISION, sitePermissions[BLUETOOTH])
+ assertEquals(NO_DECISION, sitePermissions[CAMERA])
+ assertEquals(NO_DECISION, sitePermissions[LOCAL_STORAGE])
+ assertEquals(ALLOWED, sitePermissions[AUTOPLAY_AUDIBLE])
+ assertEquals(BLOCKED, sitePermissions[AUTOPLAY_INAUDIBLE])
+ }
+
+ @Test
+ fun `AutoplayStatus - toStatus`() {
+ var sitePermissions = SitePermissions(
+ origin = "mozilla.dev",
+ autoplayInaudible = AutoplayStatus.BLOCKED,
+ autoplayAudible = AutoplayStatus.BLOCKED,
+ savedAt = 0,
+ )
+
+ assertEquals(BLOCKED, sitePermissions.autoplayAudible.toStatus())
+ assertEquals(BLOCKED, sitePermissions.autoplayInaudible.toStatus())
+
+ sitePermissions = sitePermissions.copy(
+ autoplayAudible = AutoplayStatus.ALLOWED,
+ autoplayInaudible = AutoplayStatus.ALLOWED,
+ )
+
+ assertEquals(ALLOWED, sitePermissions.autoplayAudible.toStatus())
+ assertEquals(ALLOWED, sitePermissions.autoplayInaudible.toStatus())
+ }
+
+ @Test
+ fun `Status to AutoplayStatus`() {
+ assertEquals(AutoplayStatus.BLOCKED, BLOCKED.toAutoplayStatus())
+ assertEquals(AutoplayStatus.ALLOWED, ALLOWED.toAutoplayStatus())
+ assertEquals(AutoplayStatus.BLOCKED, NO_DECISION.toAutoplayStatus())
+ }
+
+ @Test
+ fun `AutoplayStatus ids are aligned with Status`() {
+ assertEquals(AutoplayStatus.BLOCKED.id, AutoplayStatus.BLOCKED.id)
+ assertEquals(AutoplayStatus.ALLOWED, AutoplayStatus.ALLOWED)
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt
new file mode 100644
index 0000000000..5a3af2de33
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/SitePermissionEntityTest.kt
@@ -0,0 +1,86 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions.db
+
+import mozilla.components.concept.engine.permission.SitePermissions
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.BLOCKED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.NO_DECISION
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class SitePermissionEntityTest {
+
+ @Test
+ fun `convert from db entity to domain class`() {
+ val dbEntity = SitePermissionsEntity(
+ origin = "mozilla.dev",
+ localStorage = ALLOWED,
+ crossOriginStorageAccess = BLOCKED,
+ location = BLOCKED,
+ notification = NO_DECISION,
+ microphone = NO_DECISION,
+ camera = NO_DECISION,
+ bluetooth = ALLOWED,
+ autoplayInaudible = AutoplayStatus.ALLOWED,
+ autoplayAudible = AutoplayStatus.BLOCKED,
+ mediaKeySystemAccess = NO_DECISION,
+ savedAt = 0,
+ )
+
+ val domainClass = dbEntity.toSitePermission()
+
+ with(dbEntity) {
+ assertEquals(origin, domainClass.origin)
+ assertEquals(localStorage, domainClass.localStorage)
+ assertEquals(crossOriginStorageAccess, domainClass.crossOriginStorageAccess)
+ assertEquals(location, domainClass.location)
+ assertEquals(notification, domainClass.notification)
+ 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)
+ }
+ }
+
+ @Test
+ fun `convert from domain class to db entity`() {
+ val domainClass = SitePermissions(
+ origin = "mozilla.dev",
+ localStorage = ALLOWED,
+ crossOriginStorageAccess = BLOCKED,
+ location = BLOCKED,
+ notification = NO_DECISION,
+ microphone = NO_DECISION,
+ camera = NO_DECISION,
+ bluetooth = ALLOWED,
+ autoplayInaudible = AutoplayStatus.ALLOWED,
+ autoplayAudible = AutoplayStatus.BLOCKED,
+ mediaKeySystemAccess = NO_DECISION,
+ savedAt = 0,
+ )
+
+ val dbEntity = domainClass.toSitePermissionsEntity()
+
+ with(dbEntity) {
+ assertEquals(origin, domainClass.origin)
+ assertEquals(localStorage, domainClass.localStorage)
+ assertEquals(crossOriginStorageAccess, domainClass.crossOriginStorageAccess)
+ assertEquals(location, domainClass.location)
+ assertEquals(notification, domainClass.notification)
+ 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/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/StatusConverterTest.kt b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/StatusConverterTest.kt
new file mode 100644
index 0000000000..ba52476153
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/java/mozilla/components/feature/sitepermissions/db/StatusConverterTest.kt
@@ -0,0 +1,72 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.feature.sitepermissions.db
+
+import mozilla.components.concept.engine.permission.SitePermissions.AutoplayStatus
+import mozilla.components.concept.engine.permission.SitePermissions.Status.ALLOWED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.BLOCKED
+import mozilla.components.concept.engine.permission.SitePermissions.Status.NO_DECISION
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Test
+
+class StatusConverterTest {
+
+ @Test
+ fun `convert from int to status`() {
+ val converter = StatusConverter()
+
+ var status = converter.toStatus(BLOCKED.id)
+ assertEquals(status, BLOCKED)
+
+ status = converter.toStatus(NO_DECISION.id)
+ assertEquals(status, NO_DECISION)
+
+ status = converter.toStatus(ALLOWED.id)
+ assertEquals(status, ALLOWED)
+
+ status = converter.toStatus(Int.MAX_VALUE)
+ assertNull(status)
+ }
+
+ @Test
+ fun `convert from status to int`() {
+ val converter = StatusConverter()
+
+ var index = converter.toInt(ALLOWED)
+ assertEquals(index, ALLOWED.id)
+
+ index = converter.toInt(BLOCKED)
+ assertEquals(index, BLOCKED.id)
+
+ index = converter.toInt(NO_DECISION)
+ assertEquals(index, NO_DECISION.id)
+ }
+
+ @Test
+ fun `convert from int to autoplay status`() {
+ val converter = StatusConverter()
+
+ var status = converter.toAutoplayStatus(AutoplayStatus.BLOCKED.id)
+ assertEquals(status, AutoplayStatus.BLOCKED)
+
+ status = converter.toAutoplayStatus(AutoplayStatus.ALLOWED.id)
+ assertEquals(status, AutoplayStatus.ALLOWED)
+
+ status = converter.toAutoplayStatus(Int.MAX_VALUE)
+ assertEquals(AutoplayStatus.BLOCKED, status)
+ }
+
+ @Test
+ fun `convert from autoplay status to int`() {
+ val converter = StatusConverter()
+
+ var index = converter.toInt(AutoplayStatus.ALLOWED)
+ assertEquals(index, AutoplayStatus.ALLOWED.id)
+
+ index = converter.toInt(AutoplayStatus.BLOCKED)
+ assertEquals(index, AutoplayStatus.BLOCKED.id)
+ }
+}
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/mobile/android/android-components/components/feature/sitepermissions/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000..cf1c399ea8
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1,2 @@
+mock-maker-inline
+// This allows mocking final classes (classes are final by default in Kotlin)
diff --git a/mobile/android/android-components/components/feature/sitepermissions/src/test/resources/robolectric.properties b/mobile/android/android-components/components/feature/sitepermissions/src/test/resources/robolectric.properties
new file mode 100644
index 0000000000..932b01b9eb
--- /dev/null
+++ b/mobile/android/android-components/components/feature/sitepermissions/src/test/resources/robolectric.properties
@@ -0,0 +1 @@
+sdk=28