diff options
730 files changed, 19479 insertions, 3551 deletions
diff --git a/Android.bp b/Android.bp index ae681e403..7a2f39fc3 100644 --- a/Android.bp +++ b/Android.bp @@ -23,7 +23,7 @@ apex { defaults: ["com.android.permission-defaults"], manifest: "apex_manifest.json", compat_configs: [ - "framework-permission-s-compat-config" + "framework-permission-s-compat-config", ], } @@ -108,6 +108,7 @@ bootclasspath_fragment { // result in a build failure due to inconsistent flags. package_prefixes: [ "android.app.role", + "android.app.ecm", "android.permission.jarjar", "android.safetycenter", "android.safetylabel", diff --git a/PermissionController/Android.bp b/PermissionController/Android.bp index 442495df2..d825ec62f 100644 --- a/PermissionController/Android.bp +++ b/PermissionController/Android.bp @@ -53,9 +53,6 @@ java_library { srcs: [ ":statslog-permissioncontroller-java-gen", ], - lint: { - baseline_filename: "lint-baseline.xml", - }, } java_library { @@ -150,18 +147,19 @@ android_library { "lottie", "safety-label", "role-controller", - "permissions-flags-lib", + "permissions-aconfig-flags-lib", "android.permission.flags-aconfig-java", "androidx.compose.foundation_foundation", "androidx.compose.runtime_runtime", "androidx.compose.runtime_runtime-livedata", "androidx.compose.ui_ui", "androidx.wear.compose_compose-material", + "android.os.flags-aconfig-java-export", ], lint: { - strict_updatability_linting: true, error_checks: ["Recycle"], + baseline_filename: "lint-baseline.xml", }, apex_available: [ @@ -190,9 +188,7 @@ android_app { static_libs: ["PermissionController-lib"], lint: { - strict_updatability_linting: true, error_checks: ["Recycle"], - baseline_filename: "lint-baseline.xml", }, optimize: { diff --git a/PermissionController/AndroidManifest.xml b/PermissionController/AndroidManifest.xml index 0d663bc05..01e3ecefe 100644 --- a/PermissionController/AndroidManifest.xml +++ b/PermissionController/AndroidManifest.xml @@ -53,7 +53,6 @@ <uses-permission android:name="android.permission.START_VIEW_PERMISSION_USAGE" /> <uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION" /> <uses-permission android:name="android.permission.MANAGE_SENSOR_PRIVACY" /> - <uses-permission android:name="android.permission.OBSERVE_SENSOR_PRIVACY" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.MANAGE_SAFETY_CENTER" /> @@ -66,6 +65,8 @@ <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> <uses-permission android:name="android.permission.READ_APP_SPECIFIC_LOCALES" /> <uses-permission android:name="android.permission.GET_APP_METADATA" /> + <uses-permission android:name="android.permission.NFC_PREFERRED_PAYMENT_INFO" /> + <uses-permission android:name="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" /> <application android:name="com.android.permissioncontroller.PermissionControllerApplication" android:label="@string/app_name" @@ -281,6 +282,26 @@ </intent-filter> </activity> + <activity android:name="com.android.permissioncontroller.permission.ui.PermissionDialogStreamingBlockedActivity" + android:theme="@style/PermissionDialog.FilterTouches" + android:excludeFromRecents="true" + android:exported="false" + android:enabled="@bool/is_at_least_v"> + </activity> + + <activity android:name="com.android.permissioncontroller.ecm.EnhancedConfirmationDialogActivity" + android:theme="@style/Theme.EnhancedConfirmationDialog.FilterTouches" + android:excludeFromRecents="true" + android:exported="true" + android:launchMode="singleTop" + android:permission="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" + android:enabled="@bool/is_at_least_v"> + <intent-filter android:priority="1"> + <action android:name="android.app.ecm.action.SHOW_ECM_RESTRICTED_SETTING_DIALOG" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <activity android:name="com.android.permissioncontroller.permission.ui.v34.PermissionRationaleActivity" android:configChanges="keyboardHidden|screenSize" android:windowSoftInputMode="stateAlwaysHidden|adjustNothing" @@ -472,6 +493,18 @@ </intent-filter> </activity> + <activity android:name="com.android.permissioncontroller.role.ui.v35.ChangeDefaultCardEmulationActivity" + android:enabled="@bool/is_at_least_v" + android:excludeFromRecents="true" + android:noHistory="true" + android:exported="true" + android:theme="@android:style/Theme.NoDisplay"> + <intent-filter android:priority="1001"> + <action android:name="android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <provider android:name="com.android.permissioncontroller.permission.service.PermissionSearchIndexablesProvider" android:authorities="com.android.permissioncontroller" android:multiprocess="false" @@ -593,6 +626,7 @@ android:name="com.android.permissioncontroller.safetycenter.ui.SafetyCenterActivity" android:enabled="@bool/is_at_least_t" android:exported="true" + android:enableOnBackInvokedCallback="true" android:theme="@style/Theme.SafetyCenter"> <intent-filter android:priority="1"> <action android:name="android.intent.action.SAFETY_CENTER"/> diff --git a/PermissionController/TEST_MAPPING b/PermissionController/TEST_MAPPING index a7f2aec54..084670e76 100644 --- a/PermissionController/TEST_MAPPING +++ b/PermissionController/TEST_MAPPING @@ -49,6 +49,18 @@ "file_patterns": ["res/xml/roles\\.xml"] }, { + "name": "PermissionControllerMockingTests[com.google.android.permission.apex]", + "options": [ + { + "include-filter": "com.android.permissioncontroller.tests.mocking.role.model.RoleParserTest" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ], + "file_patterns": ["res/xml/roles\\.xml"] + }, + { "name": "PermissionUiTestCases[com.google.android.permission.apex]", "options": [ { @@ -108,6 +120,15 @@ "file_patterns": ["res/xml/roles\\.xml"] }, { + "name": "PermissionControllerMockingTests[com.google.android.permission.apex]", + "options": [ + { + "include-filter": "com.android.permissioncontroller.tests.mocking.role.model.RoleParserTest" + } + ], + "file_patterns": ["res/xml/roles\\.xml"] + }, + { "name": "PermissionUiTestCases[com.google.android.permission.apex]", "options": [ // TODO(b/238773220): These tests currently fails on R base image diff --git a/PermissionController/jarjar-rules.txt b/PermissionController/jarjar-rules.txt index f4d8a0be2..4df97f4c0 100644 --- a/PermissionController/jarjar-rules.txt +++ b/PermissionController/jarjar-rules.txt @@ -1 +1,2 @@ -rule android.permission.flags.** com.android.permissioncontroller.jarjar.@0 +rule android.permission.flags.*Flags* com.android.permissioncontroller.jarjar.@0 +rule android.permission.flags.Flags com.android.permissioncontroller.jarjar.@0 diff --git a/PermissionController/lint-baseline.xml b/PermissionController/lint-baseline.xml index 546ed596d..5d77d8c81 100644 --- a/PermissionController/lint-baseline.xml +++ b/PermissionController/lint-baseline.xml @@ -1,92 +1,224 @@ <?xml version="1.0" encoding="UTF-8"?> -<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev"> +<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01"> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.apphibernation.AppHibernationManager#isHibernatingForUser`" - errorLine1=" if (hibernationManager.isHibernatingForUser(pkg.packageName)) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + message="Class requires API level 34 (current min is 31): `android.app.AppOpsManager.OnOpNotedListener`" + errorLine1=" AppOpsManager.OnOpNotedListener," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/HibernatedPackagesLiveData.kt" - line="56" - column="44"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/v31/AllLightHistoricalPackageOpsLiveData.kt" + line="46" + column="5"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.content.pm.Attribution#getLabel`" - errorLine1=" attributions?.forEach { attributionTagToLabel[it.tag] = it.label }" - errorLine2=" ~~~~~"> + message="Class requires API level 34 (current min is 31): `android.app.AppOpsManager.OnOpNotedListener`" + errorLine1=" AppOpsManager.OnOpNotedListener," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPackageInfo.kt" - line="125" - column="72"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/v31/AllLightPackageOpsLiveData.kt" + line="43" + column="5"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.content.pm.Attribution#getTag`" - errorLine1=" attributions?.forEach { attributionTagToLabel[it.tag] = it.label }" - errorLine2=" ~~~"> + message="Call requires API level 33 (current min is 30): `getIconId`" + errorLine1=" .setIcon(args.getIconId())" + errorLine2=" ~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPackageInfo.kt" - line="125" - column="62"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="504" + column="31"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#canAdminGrantSensorsPermissions`" - errorLine1=" params.getGrantState(), params.canAdminGrantSensorsPermissions())));" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getMessageId`" + errorLine1=" .setMessage(args.getMessageId())" + errorLine2=" ~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" - line="517" - column="48"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="505" + column="34"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#getGrantState`" - errorLine1=" params.getGrantState(), params.canAdminGrantSensorsPermissions())));" - errorLine2=" ~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getNegativeButtonTextId`" + errorLine1=" .setNegativeButton(args.getNegativeButtonTextId()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" - line="517" - column="24"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="509" + column="41"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#getGranteePackageName`" - errorLine1=" callerPackageName, params.getGranteePackageName(), params.getPermission()," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getPositiveButtonTextId`" + errorLine1=" .setPositiveButton(args.getPositiveButtonTextId()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" - line="516" - column="43"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="513" + column="41"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#getPermission`" - errorLine1=" callerPackageName, params.getGranteePackageName(), params.getPermission()," - errorLine2=" ~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getSetOneTime`" + errorLine1=" mViewModel.requestChange(args.getSetOneTime()," + errorLine2=" ~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" - line="516" - column="75"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="515" + column="59"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.hardware.SensorPrivacyManager#addSensorPrivacyListener`" - errorLine1=" mSensorPrivacyManager.addSensorPrivacyListener(mPrivacyChangedListener);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getChangeRequest`" + errorLine1=" args.getChangeRequest()," + errorLine2=" ~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionsFragment.java" - line="159" - column="35"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="518" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getButtonClicked`" + errorLine1=" args.getButtonClicked());" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="519" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getTitleId`" + errorLine1=" if (args.getTitleId() != 0) {" + errorLine2=" ~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="521" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getTitleId`" + errorLine1=" b.setTitle(args.getTitleId());" + errorLine2=" ~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionFragment.java" + line="522" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getIconId`" + errorLine1=" .setIcon(args.getIconId())" + errorLine2=" ~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="709" + column="31"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getMessageId`" + errorLine1=" .setMessage(args.getMessageId())" + errorLine2=" ~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="710" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getNegativeButtonTextId`" + errorLine1=" .setNegativeButton(args.getNegativeButtonTextId()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="714" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getPositiveButtonTextId`" + errorLine1=" .setPositiveButton(args.getPositiveButtonTextId()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="718" + column="41"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getSetOneTime`" + errorLine1=" mViewModel.requestChange(args.getSetOneTime()," + errorLine2=" ~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="720" + column="59"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getButtonClicked`" + errorLine1=" args.getChangeRequest(), args.getButtonClicked());" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="722" + column="67"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getChangeRequest`" + errorLine1=" args.getChangeRequest(), args.getButtonClicked());" + errorLine2=" ~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="722" + column="42"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getTitleId`" + errorLine1=" if (args.getTitleId() != 0) {" + errorLine2=" ~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="724" + column="18"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `getTitleId`" + errorLine1=" b.setTitle(args.getTitleId());" + errorLine2=" ~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java" + line="725" + column="29"/> </issue> <issue @@ -95,8 +227,8 @@ errorLine1=" mSensorPrivacyManager.addSensorPrivacyListener(mPrivacyChangedListener);" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/PermissionAppsFragment.java" - line="114" + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/AppPermissionsFragment.java" + line="159" column="35"/> </issue> @@ -113,101 +245,134 @@ <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.hardware.SensorPrivacyManager#removeSensorPrivacyListener`" - errorLine1=" mSensorPrivacyManager.removeSensorPrivacyListener(mPrivacyChangedListener);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getIconId`" + errorLine1=" .setIcon(args.getIconId())" + errorLine2=" ~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/PermissionAppsFragment.java" - line="365" - column="35"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="463" + column="31"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterData#getIssues`" - errorLine1=" issues" - errorLine2=" ~~~~~~"> + message="Call requires API level 33 (current min is 30): `getMessageId`" + errorLine1=" .setMessage(args.getMessageId())" + errorLine2=" ~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="309" - column="5"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="464" + column="34"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterData#getIssues`" - errorLine1="private fun SafetyCenterData.buildIssueIdSet(): Set<IssueId> = issues.map { it.id }.toSet()" - errorLine2=" ~~~~~~"> + message="Call requires API level 33 (current min is 30): `getNegativeButtonTextId`" + errorLine1=" .setNegativeButton(args.getNegativeButtonTextId()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="323" - column="64"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="468" + column="41"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterData#getStatus`" - errorLine1=" status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS" - errorLine2=" ~~~~~~"> + message="Call requires API level 33 (current min is 30): `getPositiveButtonTextId`" + errorLine1=" .setPositiveButton(args.getPositiveButtonTextId()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="321" - column="5"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="472" + column="41"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue#getActions`" - errorLine1=" issue.actions" - errorLine2=" ~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getSetOneTime`" + errorLine1=" mViewModel.requestChange(args.getSetOneTime()," + errorLine2=" ~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="311" - column="19"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="474" + column="59"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue#getId`" - errorLine1=" .map { issue.id to it.id }" - errorLine2=" ~~"> + message="Call requires API level 33 (current min is 30): `getButtonClicked`" + errorLine1=" args.getChangeRequest(), args.getButtonClicked());" + errorLine2=" ~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="315" - column="30"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="476" + column="67"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue#getId`" - errorLine1="private fun SafetyCenterData.buildIssueIdSet(): Set<IssueId> = issues.map { it.id }.toSet()" - errorLine2=" ~~"> + message="Call requires API level 33 (current min is 30): `getChangeRequest`" + errorLine1=" args.getChangeRequest(), args.getButtonClicked());" + errorLine2=" ~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="323" - column="80"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="476" + column="42"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue.Action#getId`" - errorLine1=" .map { issue.id to it.id }" - errorLine2=" ~~"> + message="Call requires API level 33 (current min is 30): `getTitleId`" + errorLine1=" if (args.getTitleId() != 0) {" + errorLine2=" ~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="315" - column="39"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="478" + column="18"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue.Action#getSuccessMessage`" - errorLine1=" .filter { it.isInFlight && !it.successMessage.isNullOrEmpty() }" - errorLine2=" ~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `getTitleId`" + errorLine1=" b.setTitle(args.getTitleId());" + errorLine2=" ~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="314" - column="48"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java" + line="479" + column="29"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 34 (current min is 30): `android.health.connect.HealthConnectManager#isHealthPermission`" + errorLine1=" .filter { permission -> isHealthPermission(activity, permission) }" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt" + line="1059" + column="45"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 31 (current min is 30): `android.apphibernation.AppHibernationManager`" + errorLine1=" userContext.getSystemService(APP_HIBERNATION_SERVICE) as AppHibernationManager" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/HibernatedPackagesLiveData.kt" + line="48" + column="74"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 31 (current min is 30): `android.apphibernation.AppHibernationManager#isHibernatingForUser`" + errorLine1=" if (hibernationManager.isHibernatingForUser(pkg.packageName)) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/HibernatedPackagesLiveData.kt" + line="51" + column="44"/> </issue> <issue @@ -223,156 +388,167 @@ <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue.Action#isInFlight`" - errorLine1=" .filter { it.isInFlight && !it.successMessage.isNullOrEmpty() }" - errorLine2=" ~~~~~~~~~~"> + message="Call requires API level 31 (current min is 30): `android.os.UserManager#isCloneProfile`" + errorLine1=" if (userManager.isCloneProfile) {" + errorLine2=" ~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="314" - column="30"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt" + line="653" + column="29"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager#isSafetyCenterEnabled`" - errorLine1=" if (!safetyCenterManager.isSafetyCenterEnabled()) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.app.Activity#startActivityForResultAsUser`" + errorLine1=" activity.startActivityForResultAsUser(pickerIntent, requestCode, user)" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" - line="96" - column="34"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt" + line="662" + column="18"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager#isSafetyCenterEnabled`" - errorLine1=" if (!safetyCenterManager.isSafetyCenterEnabled()) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 34 (current min is 30): `android.health.connect.HealthConnectManager#getHealthPermissions`" + errorLine1=" val permissions = HealthConnectManager.getHealthPermissions(context)" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" - line="149" - column="34"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt" + line="1689" + column="48"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager#isSafetyCenterEnabled`" - errorLine1=" if (!scManager.isSafetyCenterEnabled) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 31 (current min is 30): `android.content.pm.Attribution#getLabel`" + errorLine1=" attributions?.forEach { attributionTagToLabel[it.tag] = it.label }" + errorLine2=" ~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/v33/SafetyCenterQsTileService.kt" - line="48" - column="24"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPackageInfo.kt" + line="140" + column="72"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager#refreshSafetySources`" - errorLine1=" safetyCenterManager.refreshSafetySources(getRefreshReason());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 31 (current min is 30): `android.content.pm.Attribution#getTag`" + errorLine1=" attributions?.forEach { attributionTagToLabel[it.tag] = it.label }" + errorLine2=" ~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" - line="155" - column="29"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPackageInfo.kt" + line="140" + column="62"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterStatus#getRefreshStatus`" - errorLine1=" status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS" - errorLine2=" ~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue#getActions`" + errorLine1=" issue.actions" + errorLine2=" ~~~~~~~"> <location file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" - line="321" - column="12"/> + line="288" + column="19"/> </issue> <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `recordPermissionDecision`" - errorLine1=" PermissionDecisionStorageImpl.recordPermissionDecision(app.applicationContext," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue.Action#getSuccessMessage`" + errorLine1=" .filter { it.isInFlight && !it.successMessage.isNullOrEmpty() }" + errorLine2=" ~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt" - line="1147" - column="39"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="291" + column="48"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 30): `android.content.pm.PackageManager#getAppMetadata`" - errorLine1=" app.packageManager.getAppMetadata(packageName)" - errorLine2=" ~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue.Action#isInFlight`" + errorLine1=" .filter { it.isInFlight && !it.successMessage.isNullOrEmpty() }" + errorLine2=" ~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/SafetyLabelInfoLiveData.kt" - line="116" - column="32"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="291" + column="30"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 30): `android.health.connect.HealthConnectManager#getHealthPermissions`" - errorLine1=" val permissions = HealthConnectManager.getHealthPermissions(context)" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue#getId`" + errorLine1=" .map { issue.id to it.id }" + errorLine2=" ~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt" - line="1465" - column="48"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="292" + column="30"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 30): `android.health.connect.HealthConnectManager#isHealthPermission`" - errorLine1=" isHealthPermission(activity, permission)" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue.Action#getId`" + errorLine1=" .map { issue.id to it.id }" + errorLine2=" ~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt" - line="1268" - column="17"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="292" + column="39"/> </issue> <issue id="NewApi" - message="Class requires API level 31 (current min is 30): `android.apphibernation.AppHibernationManager`" - errorLine1=" userContext.getSystemService(APP_HIBERNATION_SERVICE) as AppHibernationManager" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterData#getStatus`" + errorLine1=" status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS" + errorLine2=" ~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/HibernatedPackagesLiveData.kt" - line="53" - column="74"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="298" + column="5"/> </issue> <issue id="NewApi" - message="Class requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager`" - errorLine1=" context.getSystemService(SafetyCenterManager.class);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterStatus#getRefreshStatus`" + errorLine1=" status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS" + errorLine2=" ~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" - line="84" - column="42"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="298" + column="12"/> </issue> <issue id="NewApi" - message="Class requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager`" - errorLine1=" SafetyCenterManager safetyCenterManager = this.getSystemService(SafetyCenterManager.class);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterIssue#getId`" + errorLine1=" allResolvableIssues.map { it.id }.toSet()" + errorLine2=" ~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" - line="144" - column="73"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="301" + column="34"/> </issue> <issue id="NewApi" - message="Class requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager`" - errorLine1=" val scManager = getSystemService(SafetyCenterManager::class.java)!!" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterData#getIssues`" + errorLine1=" issues.asSequence()" + errorLine2=" ~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/v33/SafetyCenterQsTileService.kt" - line="41" - column="42"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt" + line="308" + column="13"/> + </issue> + + <issue + id="NewApi" + message="Field requires API level 33 (current min is 30): `Companion`" + errorLine1=" MoreIssuesCardPreference.TAG," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/MoreIssuesCardAnimator.kt" + line="110" + column="21"/> </issue> <issue @@ -382,88 +558,140 @@ errorLine2=" ~~~"> <location file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/MoreIssuesCardAnimator.kt" - line="107" + line="110" column="46"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.app.AppOpsManager.HistoricalOp#getDiscreteAccessAt`"> + message="Call requires API level 33 (current min is 30): `android.hardware.SensorPrivacyManager#addSensorPrivacyListener`" + errorLine1=" mSensorPrivacyManager.addSensorPrivacyListener(mPrivacyChangedListener);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightHistoricalPackageOps.kt" - line="153"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/PermissionAppsFragment.java" + line="114" + column="35"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.app.AppOpsManager.HistoricalOp#getDiscreteAccessAt`"> + message="Call requires API level 33 (current min is 30): `android.hardware.SensorPrivacyManager#removeSensorPrivacyListener`" + errorLine1=" mSensorPrivacyManager.removeSensorPrivacyListener(mPrivacyChangedListener);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightHistoricalPackageOps.kt" - line="188"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/television/PermissionAppsFragment.java" + line="365" + column="35"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.app.AppOpsManager.HistoricalOp#getDiscreteAccessCount`"> + message="Call requires API level 31 (current min is 30): `SensorStatusLiveData`" + errorLine1=" lazy(LazyThreadSafetyMode.NONE) { SensorStatusLiveData() }" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightHistoricalPackageOps.kt" - line="152"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/PermissionAppsViewModel.kt" + line="100" + column="43"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.app.AppOpsManager.HistoricalOp#getDiscreteAccessCount`"> + message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#getGranteePackageName`" + errorLine1=" callerPackageName, params.getGranteePackageName(), params.getPermission()," + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightHistoricalPackageOps.kt" - line="187"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" + line="521" + column="43"/> </issue> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.app.AppOpsManager.HistoricalOpsRequest.Builder#setHistoryFlags`"> + message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#getPermission`" + errorLine1=" callerPackageName, params.getGranteePackageName(), params.getPermission()," + errorLine2=" ~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/v31/AllLightHistoricalPackageOpsLiveData.kt" - line="104"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" + line="521" + column="75"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 33): `getParentGroupId`"> + message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#canAdminGrantSensorsPermissions`" + errorLine1=" params.getGrantState(), params.canAdminGrantSensorsPermissions())));" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterActivity.java" - line="91"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" + line="522" + column="48"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 33): `openRelevantSubpage`"> + message="Call requires API level 31 (current min is 30): `android.permission.AdminPermissionControlParams#getGrantState`" + errorLine1=" params.getGrantState(), params.canAdminGrantSensorsPermissions())));" + errorLine2=" ~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterActivity.java" - line="88"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java" + line="522" + column="24"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 33): `openRelevantSubpage`"> + message="Class requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager`" + errorLine1=" context.getSystemService(SafetyCenterManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterActivity.java" - line="92"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" + line="85" + column="42"/> </issue> <issue id="NewApi" - message="Class requires API level 34 (current min is 30): `android.app.AppOpsManager.OnOpNotedListener`"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager#isSafetyCenterEnabled`" + errorLine1=" if (!safetyCenterManager.isSafetyCenterEnabled()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/v31/AllLightHistoricalPackageOpsLiveData.kt" - line="46"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" + line="97" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Class requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager`" + errorLine1=" SafetyCenterManager safetyCenterManager = this.getSystemService(SafetyCenterManager.class);" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" + line="141" + column="73"/> </issue> <issue id="NewApi" - message="Class requires API level 34 (current min is 30): `android.app.AppOpsManager.OnOpNotedListener`"> + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager#isSafetyCenterEnabled`" + errorLine1=" if (!safetyCenterManager.isSafetyCenterEnabled()) {" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/data/v31/AllLightPackageOpsLiveData.kt" - line="43"/> + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" + line="146" + column="34"/> + </issue> + + <issue + id="NewApi" + message="Call requires API level 33 (current min is 30): `android.safetycenter.SafetyCenterManager#refreshSafetySources`" + errorLine1=" safetyCenterManager.refreshSafetySources(getRefreshReason());" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> + <location + file="packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterBackgroundRefreshJobService.java" + line="152" + column="29"/> </issue> </issues>
\ No newline at end of file diff --git a/PermissionController/res/drawable/ic_lock_closed.xml b/PermissionController/res/drawable/ic_lock_closed.xml new file mode 100644 index 000000000..e61a2d4a5 --- /dev/null +++ b/PermissionController/res/drawable/ic_lock_closed.xml @@ -0,0 +1,28 @@ +<!-- + Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,15m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/> + <path + android:fillColor="@android:color/white" + android:pathData="M18,8h-1.5V5.5C16.5,3.01 14.49,1 12,1S7.5,3.01 7.5,5.5V8H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9.5,5.5C9.5,4.12 10.62,3 12,3c1.38,0 2.5,1.12 2.5,2.5V8h-5V5.5zM18,20H6V10h1.5h9H18V20z"/> +</vector> diff --git a/PermissionController/res/layout-v33/view_more_issues.xml b/PermissionController/res/layout-v33/view_more_issues.xml index e1db725ad..7365e11c5 100644 --- a/PermissionController/res/layout-v33/view_more_issues.xml +++ b/PermissionController/res/layout-v33/view_more_issues.xml @@ -15,31 +15,58 @@ --> <merge xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto" tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> <ImageView android:id="@+id/status_icon" android:importantForAccessibility="no" android:src="@drawable/safety_status_info" - style="@style/SafetyCenterMoreIssuesIcon"/> + style="@style/SafetyCenterMoreIssuesIcon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@+id/title"/> <TextView - android:id="@+id/title" - style="@style/SafetyCenterMoreIssuesTitle"/> + android:id="@id/title" + style="@style/SafetyCenterMoreIssuesTitle" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/status_icon" + app:layout_constraintEnd_toStartOf="@+id/widget_title"/> - <LinearLayout - android:id="@android:id/widget_frame" - style="@style/SafetyCenterMoreIssuesCounter"> + <View + android:id="@+id/widget_background" + style="@style/SafetyCenterMoreIssuesCounter" + app:layout_constraintTop_toTopOf="@id/widget_title" + app:layout_constraintBottom_toBottomOf="@id/widget_title" + app:layout_constraintStart_toStartOf="@id/widget_title" + app:layout_constraintEnd_toEndOf="parent"/> - <TextView - android:id="@+id/widget_title" - style="@style/SafetyCenterMoreIssuesWidgetTitle" /> + <TextView + android:id="@id/widget_title" + style="@style/SafetyCenterMoreIssuesWidgetTitle" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/title" + app:layout_constraintEnd_toStartOf="@+id/widget_icon"/> + + <ImageView + android:id="@id/widget_icon" + android:importantForAccessibility="no" + style="@style/SafetyCenterMoreIssuesWidgetIcon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/widget_title" + app:layout_constraintEnd_toEndOf="parent"/> - <ImageView - android:id="@+id/widget_icon" - android:importantForAccessibility="no" - style="@style/SafetyCenterMoreIssuesWidgetIcon" /> + <androidx.constraintlayout.widget.Group + android:id="@+id/widget_frame" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="visible" + app:constraint_referenced_ids="widget_background,widget_title,widget_icon"/> - </LinearLayout> -</merge>
\ No newline at end of file +</merge> diff --git a/PermissionController/res/layout/app_permission.xml b/PermissionController/res/layout/app_permission.xml index 7e24207fe..1d0b7dc0c 100644 --- a/PermissionController/res/layout/app_permission.xml +++ b/PermissionController/res/layout/app_permission.xml @@ -83,10 +83,17 @@ android:id="@+id/permission_message" style="@style/AppPermissionMessage" /> - <RadioButton - android:id="@+id/allow_radio_button" - android:text="@string/app_permission_button_allow" - style="@style/AppPermissionRadioButton" /> + <FrameLayout + android:id="@+id/allow_radio_button_frame" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <RadioButton + android:id="@+id/allow_radio_button" + android:text="@string/app_permission_button_allow" + android:clickable="false" + android:focusable="false" + style="@style/AppPermissionRadioButton" /> + </FrameLayout> <RadioButton android:id="@+id/allow_always_radio_button" diff --git a/PermissionController/res/layout/enhanced_confirmation_dialog.xml b/PermissionController/res/layout/enhanced_confirmation_dialog.xml new file mode 100644 index 000000000..dde2e3f69 --- /dev/null +++ b/PermissionController/res/layout/enhanced_confirmation_dialog.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/enhanced_confirmation_dialog" + style="@style/EnhancedConfirmationDialog"> + <LinearLayout + android:id="@+id/enhanced_confirmation_dialog_header" + style="@style/EnhancedConfirmationDialogHeader"> + <ImageView + android:id="@+id/enhanced_confirmation_dialog_icon" + style="@style/EnhancedConfirmationDialogIcon" /> + <TextView + android:id="@+id/enhanced_confirmation_dialog_title" + android:text="@string/enhanced_confirmation_dialog_title" + style="@style/EnhancedConfirmationDialogTitle" /> + </LinearLayout> + + <ScrollView + android:id="@+id/enhanced_confirmation_dialog_scrollview" + style="@style/EnhancedConfirmationDialogScrollView"> + <LinearLayout + android:id="@+id/enhanced_confirmation_dialog_body" + style="@style/EnhancedConfirmationDialogBody"> + <TextView + android:id="@+id/enhanced_confirmation_dialog_desc" + android:text="@string/enhanced_confirmation_dialog_desc" + style="@style/EnhancedConfirmationDialogDesc" /> + </LinearLayout> + </ScrollView> +</LinearLayout> diff --git a/PermissionController/res/layout/request_role_item.xml b/PermissionController/res/layout/request_role_item.xml index d7d142289..39e458aa2 100644 --- a/PermissionController/res/layout/request_role_item.xml +++ b/PermissionController/res/layout/request_role_item.xml @@ -24,28 +24,23 @@ <ImageView android:id="@+id/icon" - android:duplicateParentState="true" style="@style/RequestRoleItemIcon" /> <LinearLayout android:id="@+id/title_and_subtitle" - android:duplicateParentState="true" style="@style/RequestRoleItemTitleLayout"> <TextView android:id="@+id/title" - android:duplicateParentState="true" style="@style/RequestRoleItemTitleText" /> <TextView android:id="@+id/subtitle" - android:duplicateParentState="true" style="@style/RequestRoleItemSubtitleText" /> </LinearLayout> <RadioButton android:clickable="false" - android:duplicateParentState="true" android:focusable="false" style="@style/RequestRoleItemRadioButton" /> </com.android.permissioncontroller.role.ui.CheckableLinearLayout> diff --git a/PermissionController/res/values-af-v34/strings.xml b/PermissionController/res/values-af-v34/strings.xml index db69a7032..9a423aa78 100644 --- a/PermissionController/res/values-af-v34/strings.xml +++ b/PermissionController/res/values-af-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Bestuur apptoegang tot gesondheidsdata"</string> <string name="location_settings" msgid="8863940440881290182">"Liggingtoegang"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Vir apps en dienste. As hierdie instelling af is, kan mikrofoondata steeds gedeel word wanneer jy ’n noodnommer bel"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Vir apps en dienste"</string> </resources> diff --git a/PermissionController/res/values-af-watch/strings.xml b/PermissionController/res/values-af-watch/strings.xml index 3386aa514..c6cfd6038 100644 --- a/PermissionController/res/values-af-watch/strings.xml +++ b/PermissionController/res/values-af-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Onveranderbaar"</string> <string name="generic_yes" msgid="2489207724988649846">"Ja"</string> <string name="generic_cancel" msgid="2631708607129269698">"Kanselleer"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Altyd"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Terwyl app gebruik word"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Altyd"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Terwyl app gebruik word"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Altyd"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Terwyl app gebruik word"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Altyd"</string> </resources> diff --git a/PermissionController/res/values-af/strings.xml b/PermissionController/res/values-af/strings.xml index 0f9558fb4..ea71d7004 100644 --- a/PermissionController/res/values-af/strings.xml +++ b/PermissionController/res/values-af/strings.xml @@ -51,7 +51,7 @@ <string name="permission_revoked_none" msgid="9213345075484381180">"geen is gedeaktiveer nie"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"Laat toe"</string> <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Laat altyd toe"</string> - <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Terwyl die program gebruik word"</string> + <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Terwyl die app gebruik word"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"Verander na presiese ligging"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"Hou benaderde ligging"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"Net hierdie keer"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Alle toestemmings"</string> <string name="other_permissions" msgid="2901186127193849594">"Ander programvermoëns"</string> <string name="permission_request_title" msgid="8790310151025020126">"Toestemmingsversoek"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Installeer- en deïnstalleerhandelinge word nie in Wear gesteun nie."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Kies waartoe <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang mag kry"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> is opgedateer. Kies waartoe hierdie program toegang mag kry."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Kanselleer"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Wanneer presiese ligging af is, kan programme jou benaderde ligging bepaal"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>-toestemming"</string> <string name="app_permission_header" msgid="2951363137032603806">"Toegang tot <xliff:g id="PERM">%1$s</xliff:g> vir hierdie program"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g>toegang vir hierdie app op <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Sien al <xliff:g id="APP">%1$s</xliff:g> se toestemmings"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Sien alle programme met hierdie toestemming"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Wys Assistent-mikrofoongebruik"</string> - <string name="unused_apps_category_title" msgid="2988455616845243901">"Ongebruikte programinstellings"</string> + <string name="unused_apps_category_title" msgid="2988455616845243901">"Instellings vir ongebruikte apps"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"Verwyder toestemmings as program nie gebruik word nie"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Verwyder toestemmings en maak spasie beskikbaar"</string> - <string name="unused_apps_label_v2" msgid="7058776770056517980">"Onderbreek programaktiwiteit as ongebruik"</string> + <string name="unused_apps_label_v2" msgid="7058776770056517980">"Onderbreek appaktiwiteit as ongebruik"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Bestuur app indien ongebruik"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Verwyder toestemmings, vee tydelike lêers uit, en stop kennisgewings"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Verwyder toestemmings, vee tydelike lêers uit, stop kennisgewings en argiveer die app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Om jou data te beskerm, sal toestemmings vir hierdie program verwyder word as die program \'n paar maande nie gebruik word nie."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Om jou data te beskerm, sal die volgende toestemmings verwyder word as dit vir \'n paar maande nie gebruik word nie: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Om jou data te beskerm, is toestemmings verwyder van programme wat jy \'n paar maande gelede laas gebruik het."</string> @@ -234,8 +235,8 @@ <string name="permission_description_summary_call_log" msgid="7321437186317577624">"Programme met hierdie toestemming kan foonoproeprekord lees en skryf"</string> <string name="permission_description_summary_camera" msgid="108004375101882069">"Programme met hierdie toestemming kan foto\'s neem en video\'s opneem"</string> <string name="permission_description_summary_contacts" msgid="2337798886460408996">"Programme met hierdie toestemming kan toegang tot jou kontakte kry"</string> - <string name="permission_description_summary_location" msgid="2817531799933480694">"Programme met hierdie toestemming kan toegang tot jou toestel se ligging kry"</string> - <string name="permission_description_summary_nearby_devices" msgid="8269183818275073741">"Programme met hierdie toestemming kan toestelle in die omtrek soek, aan hulle koppel en hul relatiewe posisie bepaal"</string> + <string name="permission_description_summary_location" msgid="2817531799933480694">"Apps met hierdie toestemming kan toegang tot jou toestel se ligging kry"</string> + <string name="permission_description_summary_nearby_devices" msgid="8269183818275073741">"Apps met hierdie toestemming kan toestelle in die omtrek soek, aan hulle koppel en hul relatiewe posisie bepaal"</string> <string name="permission_description_summary_microphone" msgid="630834800308329907">"Programme met hierdie toestemming kan oudio opneem"</string> <string name="permission_description_summary_phone" msgid="4515277217435233619">"Programme met hierdie toestemming kan foonoproepe maak en bestuur"</string> <string name="permission_description_summary_sensors" msgid="1836045815643119949">"Programme met hierdie toestemming kan toegang kry tot sensordata oor jou lewenstekens"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Toegelaat om alle lêers te bestuur"</string> <string name="ask_header" msgid="2633816846459944376">"Vra elke keer"</string> <string name="denied_header" msgid="903209608358177654">"Nie toegelaat nie"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> op <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Sien meer programme wat toegang tot alle lêers het"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dag}other{# dae}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# uur}other{# uur}}"</string> @@ -350,10 +352,10 @@ <string name="accessibility_service_dialog_bottom_text_single" msgid="1128666197822205958">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kan jou skerm, handelinge en invoere bekyk, handelinge uitvoer, en die skerm beheer."</string> <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"Hierdie programme kan jou skerm, handelinge en invoere bekyk, handelinge uitvoer, en die skerm beheer."</string> <string name="role_assistant_label" msgid="4727586018198208128">"Verstekdigitaleassistentprogram"</string> - <string name="role_assistant_short_label" msgid="3369003713187703399">"Digitaleassistentprogram"</string> + <string name="role_assistant_short_label" msgid="3369003713187703399">"Digitaleassistentapp"</string> <string name="role_assistant_description" msgid="6622458130459922952">"Bystandprogramme kan jou help op grond van inligting vanaf die skerm waarna jy kyk. Sommige programme steun sowel lanseerder- as steminvoerdienste om vir jou geïntegreerde bystand te gee."</string> <string name="role_browser_label" msgid="2877796144554070207">"Verstekblaaier"</string> - <string name="role_browser_short_label" msgid="6745009127123292296">"Blaaierprogram"</string> + <string name="role_browser_short_label" msgid="6745009127123292296">"Blaaierapp"</string> <string name="role_browser_description" msgid="3465253637499842671">"Programme wat jou toegang tot die internet gee en na vertoonskakels waarop jy tik"</string> <string name="role_browser_request_title" msgid="2895200507835937192">"Stel <xliff:g id="APP_NAME">%1$s</xliff:g> as jou verstekblaaierprogram?"</string> <string name="role_browser_request_description" msgid="5888803407905985941">"Geen toestemmings is nodig nie"</string> @@ -364,7 +366,7 @@ <string name="role_dialer_request_description" msgid="6288839625724909320">"Hierdie program sal toegang tot jou kamera, kontakte, mikrofoon, foon en SMS\'e kry"</string> <string name="role_dialer_search_keywords" msgid="3324448983559188087">"beller"</string> <string name="role_sms_label" msgid="8456999857547686640">"Verstek-SMS-program"</string> - <string name="role_sms_short_label" msgid="4371444488034692243">"SMS-program"</string> + <string name="role_sms_short_label" msgid="4371444488034692243">"SMS-app"</string> <string name="role_sms_description" msgid="3424020199148153513">"Programme wat jou toelaat om jou foonnommer te gebruik om kort SMS\'e, foto\'s, video\'s en meer te stuur en te ontvang"</string> <string name="role_sms_request_title" msgid="7953552109601185602">"Stel <xliff:g id="APP_NAME">%1$s</xliff:g> as jou verstek-SMS-program?"</string> <string name="role_sms_request_description" msgid="2691004766132144886">"Hierdie program sal toegang tot jou kamera, kontakte, lêers en media, mikrofoon, foon en SMS\'e kry"</string> @@ -376,7 +378,7 @@ <string name="role_emergency_request_description" msgid="131645948770262850">"Geen toestemmings is nodig nie"</string> <string name="role_emergency_search_keywords" msgid="1920007722599213358">"ice"</string> <string name="role_home_label" msgid="3871847846649769412">"Verstekhuisprogram"</string> - <string name="role_home_short_label" msgid="8544733747952272337">"Huisprogram"</string> + <string name="role_home_short_label" msgid="8544733747952272337">"Home-app"</string> <string name="role_home_description" msgid="7997371519626556675">"Programme, wat dikwels lanseerders genoem word, wat die Tuisskerms op jou Android-toestel vervang en vir jou toegang gee tot die inhoud en kenmerke van jou toestel"</string> <string name="role_home_request_title" msgid="738136983453341081">"Stel <xliff:g id="APP_NAME">%1$s</xliff:g> as jou verstekhuisprogram?"</string> <string name="role_home_request_description" msgid="2658833966716057673">"Geen toestemmings is nodig nie"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notasapp"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps wat jou toelaat om notas op jou toestel te maak"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notas"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Verstekbeursie-app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Beursie-app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Beursie-apps kan jou krediet- en lojaliteitskaarte, motorsleutels en ander goed stoor om met verskeie vorme van transaksies te help."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Stel <xliff:g id="APP_NAME">%1$s</xliff:g> as jou verstekbeursie-app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Geen toestemmings is nodig nie"</string> <string name="request_role_current_default" msgid="738722892438247184">"Huidige verstek"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Moenie weer vra nie"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Stel as verstek"</string> @@ -420,10 +427,10 @@ <string name="ongoing_usage_dialog_title_mic_camera" msgid="9079747867228772797">"Onlangse gebruik van mikrofoon en kamera"</string> <string name="ongoing_usage_dialog_separator" msgid="1715181526581520068">", "</string> <string name="ongoing_usage_dialog_last_separator" msgid="4170995004748832163">" en "</string> - <string name="default_app_search_keyword" msgid="8330125736889689743">"verstekprogramme"</string> + <string name="default_app_search_keyword" msgid="8330125736889689743">"verstekapps"</string> <string name="permgroup_list_microphone_and_camera" msgid="962768198001487969">"Mikrofoon en kamera"</string> <string name="settings_button" msgid="4414988414732479636">"Instellings"</string> - <string name="default_apps" msgid="5119201969348748639">"Verstekprogramme"</string> + <string name="default_apps" msgid="5119201969348748639">"Verstekapps"</string> <string name="no_default_apps" msgid="2593466527182950231">"Geen verstekprogramme nie"</string> <string name="default_apps_more" msgid="4078194675848858093">"Meer verstekke"</string> <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Oopmaak van skakels"</string> @@ -546,7 +553,7 @@ <string name="blocked_camera_title" msgid="1128510551791284384">"Toestelkamera is geblokkeer"</string> <string name="blocked_microphone_title" msgid="1631517143648232585">"Toestelmikrofoon is geblokkeer"</string> <string name="blocked_location_title" msgid="2005608279812892383">"Toestelligging is af"</string> - <string name="blocked_sensor_summary" msgid="4443707628305027375">"Vir programme en dienste"</string> + <string name="blocked_sensor_summary" msgid="4443707628305027375">"Vir apps en dienste"</string> <string name="blocked_mic_summary" msgid="8960466941528458347">"Mikrofoondata kan steeds gedeel word wanneer jy \'n noodnommer bel."</string> <string name="blocked_sensor_button_label" msgid="6742092634984289658">"Verander"</string> <string name="safety_center_dashboard_page_title" msgid="2810774008694315854">"Sekuriteit en privaatheid"</string> @@ -610,7 +617,7 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"Mikrofoontoegang"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Vir apps en dienste"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Vir apps en dienste. As hierdie instelling af is, kan mikrofoondata steeds gedeel word wanneer jy ’n noodnommer bel."</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"Sien programme en dienste met toegang tot ligging"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"Sien apps en dienste met toegang tot ligging"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Wys knipbordtoegang"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Wys ’n boodskap wanneer apps toegang het tot teks, prente of ander inhoud wat jy gekopieer het"</string> <string name="show_password_title" msgid="2877269286984684659">"Wys wagwoorde"</string> @@ -648,4 +655,26 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Datadelingopdaterings"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Sommige apps het die manier waarop hulle jou liggingdata kan deel, verander"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Instellings"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Ingegaan <xliff:g id="TIME_DATE">%1$s</xliff:g>."</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Gister ingegaan <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Ingegaan <xliff:g id="TIME_DATE_0">%1$s</xliff:g><xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Jou eenmalige wagwoord is 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Beperkte instelling"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Hierdie instelling is vir jou veiligheid tans onbeskikbaar."</string> + <!-- no translation found for enhanced_confirmation_dialog_title_permission (2149144789394238266) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_permission (3150778951946468945) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_title_role (1737023798483772780) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_role (6369601947905234551) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_title_settings_default (1858092969721041576) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_settings_default (6911632348359332981) --> + <skip /> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Meer inligting"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Toestemmingsversoek is onderdruk"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Hierdie app versoek bykomende toestemmings, maar toestemmings kan nie in ’n stromingsessie verleen word nie. Verleen eers die toestemming op jou foon."</string> </resources> diff --git a/PermissionController/res/values-am-v34/strings.xml b/PermissionController/res/values-am-v34/strings.xml index 52f5188ba..9b3edef01 100644 --- a/PermissionController/res/values-am-v34/strings.xml +++ b/PermissionController/res/values-am-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"የመተግበሪያ የጤና ውሂብ መዳረሻን ያስተዳድሩ"</string> <string name="location_settings" msgid="8863940440881290182">"የአካባቢ መዳረሻ"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ለመተግበሪያዎች እና አገልግሎቶች። ይህ ቅንብር ከጠፋ እርስዎ ወደ አንድ የአደጋ ጊዜ ቁጥር ሲደውሉ የማይክሮፎን ውሂብ አሁንም ሊጋራ ይችላል"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ለመተግበሪያዎች እና አገልግሎቶች"</string> </resources> diff --git a/PermissionController/res/values-am-watch/strings.xml b/PermissionController/res/values-am-watch/strings.xml index 69a852865..463161920 100644 --- a/PermissionController/res/values-am-watch/strings.xml +++ b/PermissionController/res/values-am-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ሊለወጥ አይችልም"</string> <string name="generic_yes" msgid="2489207724988649846">"አዎ"</string> <string name="generic_cancel" msgid="2631708607129269698">"ይቅር"</string> + <string name="permission_access_always" msgid="2107115233573823032">"ሁልጊዜ"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"መተግበሪያ እየተጠቀሙ ሳለ"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"ሁልጊዜ"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"መተግበሪያ እየተጠቀሙ ሳለ"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"ሁልጊዜ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"መተግበሪያ እየተጠቀሙ ሳለ"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"ሁልጊዜ"</string> </resources> diff --git a/PermissionController/res/values-am/strings.xml b/PermissionController/res/values-am/strings.xml index de2e0c8d8..927b71141 100644 --- a/PermissionController/res/values-am/strings.xml +++ b/PermissionController/res/values-am/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ሁሉም ፍቃዶች"</string> <string name="other_permissions" msgid="2901186127193849594">"ሌሎች የመተግበሪያ ችሎታዎች"</string> <string name="permission_request_title" msgid="8790310151025020126">"የፍቃድ ጥያቄ"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"በWear ላይ የመጫን/ማራገፍ እርምጃዎች አይደገፉም።"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ምን መድረስ እንደሚችል ይምረጡ"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ተዘምኗል። ይህ መተግበሪያ ምን መድረስ እንደሚችል ይምረጡ።"</string> <string name="review_button_cancel" msgid="2191147944056548886">"ይቅር"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"ትክክለኛ አካባቢ ሲጠፋ መተግበሪያዎች ግምታዊ አካባቢዎን መድረስ ይችላሉ"</string> <string name="app_permission_title" msgid="2090897901051370711">"የ<xliff:g id="PERM">%1$s</xliff:g> ፈቃድ"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> መዳረሻ ለዚህ መተግበሪያ"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> ላይ ለዚህ መተግበሪያ የ<xliff:g id="PERM">%1$s</xliff:g> መዳረሻ"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"ሁሉንም <xliff:g id="APP">%1$s</xliff:g> ፈቃዶች ይመልከቱ"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ከዚህ መተግበሪያ ጋር ሁሉንም መተግበሪያዎች ይመልከቱ"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"የረዳት ማይክሮፎን አጠቃቀምን አሳይ"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"መተግበሪያ ጥቅም ላይ ካልዋለ ፈቃዶችን አስወግድ"</string> <string name="unused_apps_label" msgid="2595428768404901064">"ፈቃዶችን ያስወግዱ እና ቦታ ያስለቅቁ"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"የመተግበሪያ እንቅስቃሴ ሥራ ላይ ካልዋለ ባለበት አቁም"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ጥቅም ላይ ካልዋለ መተግበሪያን ያስተዳድሩ"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ፈቃዶችን አስወግድ፣ ጊዜያዊ ፋይሎችን ሰርዝ እና ማሳወቂያዎችን አቁም"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ፈቃዶችን ያስወግዱ፣ ጊዜያዊ ፋይሎችን ይሰርዙ፣ ማሳወቂያዎችን ያቁሙ እና መተግበሪያውን በማህደር ያስቀምጡ"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"ለእርስዎ ውሂብ ጥበቃ ለማድረግ፣ ለዚህ መተግበሪያ የተሰጡ ፈቃዶች መተግበሪያው ለጥቂት ወራት ጥቅም ላይ ካልዋለ ይህ መተግበሪያ ይወገዳል።"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"የእርስዎን ውሂብ ለመጠበቅ፣ መተግበሪያው ለጥቂት ወራት ጥቅም ላይ ካልዋለ፣ የሚከተሉት ፈቃዶች ይወገዳሉ፦ <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"የእርስዎን ውሂብ ለመጠበቅ ሲባል ለጥቂት ወራት ካልተጠቀሙባቸው መተግበሪያዎች ላይ ፈቃዶች ተወግደዋል።"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ሁሉንም ፋይሎች ማስተዳደር ተፈቀዷል"</string> <string name="ask_header" msgid="2633816846459944376">"ሁልጊዜ ጠይቅ"</string> <string name="denied_header" msgid="903209608358177654">"አይፈቀድም"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> በ<xliff:g id="DEVICE_NAME">%2$s</xliff:g> ላይ"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ሁሉንም ፋይሎች መድረስ የሚችሉ ተጨማሪ መተግበሪያዎችን ይመልከቱ"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ቀን}one{# ቀኖች}other{# ቀኖች}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ሰዓት}one{# ሰዓት}other{# ሰዓታት}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"የማስታወሻዎች መተግበሪያ"</string> <string name="role_notes_description" msgid="8496852798616883551">"በመሣሪያዎ ላይ ማስታወሻ እንዲይዙ የሚያስችሉዎት መተግበሪያዎች"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ማስታወሻዎች"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ነባሪ የwallet መተግበሪያ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"የwallet መተግበሪያ"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"የWallet መተግበሪያዎች የተለያዩ የግብይት ዓይነቶችን ለማገዝ የክሬዲትና የታማኝነት ካርዶችዎን፣ የመኪና ቁልፎችዎን እና ሌሎች ነገሮችን ማከማቸት ይችላሉ።"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> እንደ ነባሪ የWallet መተግበሪያዎ ይቀናበር?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ምንም ፈቃዶች አያስፈልጉም"</string> <string name="request_role_current_default" msgid="738722892438247184">"አሁን ያለ ነባሪ"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ዳግም አትጠይቅ"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"እንደ ነባሪ አዘጋጅ"</string> @@ -503,10 +510,10 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"ይህ መተግበሪያ መተግበሪያውን በማይጠቀሙበት ጊዜም እንኳ ሁልጊዜ ኦዲዮ መቅዳት ይፈልጋል። "<annotation id="link">"በቅንብሮች ውስጥ ይፍቀዱ።"</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> የእርስዎን አካላዊ እንቅስቃሴ እንዲደርስበት ይፈቀድለት?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> በእርስዎ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> ላይ አካላዊ እንቅስቃሴዎን እንዲደርስ ይፈቀድለት?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ስዕሎችን እንዲያነሳ እና ቪዲዮን እንዲቀርጽ ይፈቀድለት?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ሥዕሎችን እንዲያነሳ እና ቪዲዮን እንዲቀርጽ ይፈቀድለት?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> በእርስዎ <b><xliff:g id="DEVICE">%2$s</xliff:g></b>? ላይ ሥዕሎችን እንዲያነሳ እና ቪድዮ እንዲቀርጽ ይፈቀድለት?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"መተግበሪያው ስዕሎችን ማንሳት እና ቪዲዮውን መቅዳት የሚችለው መተግበሪያውን እርስዎ ሲጠቀሙበት ብቻ ነው"</string> - <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ስዕሎችን እንዲያነሳ እና ቪዲዮን እንዲቀርጽ ይፈቀድለት?"</string> + <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ሥዕሎችን እንዲያነሳ እና ቪዲዮን እንዲቀርጽ ይፈቀድለት?"</string> <string name="permgroupbackgroundrequest_device_aware_camera" msgid="6718286540040964849">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> በእርስዎ <b><xliff:g id="DEVICE">%2$s</xliff:g></b>? ላይ ሥዕሎችን እንዲያነሳ እና ቪድዮ እንዲቀርጽ ይፈቀድለት?"</string> <string name="permgroupbackgroundrequestdetail_camera" msgid="4458783509089859078">"ይህ መተግበሪያ መተግበሪያውን በማይጠቀሙበት ጊዜም እንኳ ሁልጊዜ ሥዕሎችን ማንሳት እና ቪዲዮ መቅዳት ሊፈልግ ይችላል። "<annotation id="link">"በቅንብሮች ውስጥ ይፍቀዱ።"</annotation></string> <string name="permgroupupgraderequest_camera" msgid="640758449200241582">"ለ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> የካሜራ መዳረሻ ይለወጥ?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"የውሂብ ማጋራት ዝማኔዎች"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"አንዳንድ መተግበሪያዎች የእርስዎን የአካባቢ ውሂብ ሊያጋሩ የሚችሉበትን መንገድ ለውጠዋል"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ቅንብሮች"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"በ<xliff:g id="TIME_DATE">%1$s</xliff:g> ላይ ተደርስበታል"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"ትላንት በ<xliff:g id="TIME_DATE">%1$s</xliff:g> ላይ ተደርስበታል"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"በ<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g> ላይ ተደርስበታል"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"የአንድ ጊዜ የይለፍ ቃልዎ 132435 ነው"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"የተገደበ ቅንብር"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"ለእርስዎ ደህንነት ሲባል ይህ ቅንብር በአሁኑ ጊዜ አይገኝም።"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"መተግበሪያ የ<xliff:g id="PERMISSION_NAME">%1$s</xliff:g> መዳረሻ ተከልክሏል"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"መተግበሪያው የእርስዎን የግል እና የፋይናንስ መረጃ አደጋ ላይ የሚጥል አደገኛ ፈቃድ እንዲደርስ ጠይቋል።<xliff:g id="ID_1"><br><br></xliff:g>ያለዚህ የተገደበ ፈቃድ መተግበሪያው በትክክል ላይሰራ ይችላል። <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>እንዴት መዳረሻን እንደሚፈቅዱ ይረዱ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"መተግበሪያ ነባሪ <xliff:g id="ROLE_NAME">%1$s</xliff:g> የመሆን መዳረሻ ተከልክሏል"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"መተግበሪያው የእርስዎን የግል እና የፋይናንስ መረጃ አደጋ ላይ የሚጥል አደገኛ ፈቃድ እንዲደርስ ጠይቋል።<xliff:g id="ID_1"><br><br></xliff:g>ያለዚህ የተገደበ ፈቃድ መተግበሪያው በትክክል ላይሰራ ይችላል። <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>እንዴት መዳረሻን እንደሚፈቅዱ ይረዱ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"መተግበሪያ መዳረሻ ተከልክሏል"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"የዚህ ፈቃድ መዳረሻ የእርስዎን የግል እና የፋይናንስ መረጃ አደጋ ላይ ሊጥል ይችላል።<xliff:g id="ID_1"><br><br></xliff:g>ያለዚህ የተገደበ ፈቃድ መተግበሪያው በትክክል ላይሰራ ይችላል። <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>እንዴት መዳረሻን እንደሚፈቅዱ ይረዱ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"የበለጠ ለመረዳት"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"እሺ"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"የፈቃድ ጥያቄ ታፍኗል"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ይህ መተግበሪያ ተጨማሪ ፈቃዶችን እየጠየቀ ነው፣ ነገር ግን ፈቃዶች በዥረት ክፍለ ጊዜ ውስጥ ሊሰጡ አይችሉም። መጀመሪያ በስልክዎ ላይ ፈቃድ ይስጡ።"</string> </resources> diff --git a/PermissionController/res/values-ar-v34/strings.xml b/PermissionController/res/values-ar-v34/strings.xml index 5a0d25e63..af7442dbd 100644 --- a/PermissionController/res/values-ar-v34/strings.xml +++ b/PermissionController/res/values-ar-v34/strings.xml @@ -22,6 +22,5 @@ <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> <string name="health_connect_summary" msgid="815473513776882296">"إدارة إمكانية وصول التطبيقات إلى البيانات الصحية"</string> <string name="location_settings" msgid="8863940440881290182">"الوصول إلى الموقع الجغرافي"</string> - <string name="mic_toggle_description" msgid="1504101620086616040">"للتطبيقات والخدمات: إذا كان هذا الخيار غير مفعّل، ستستمر إمكانية مشاركة بيانات الميكروفون عند الاتصال برقم طوارئ."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"للتطبيقات والخدمات"</string> + <string name="mic_toggle_description" msgid="1504101620086616040">"للتطبيقات والخدمات. إذا كان هذا الخيار غير مفعّل، قد تتم مشاركة بيانات الميكروفون عند الاتصال برقم طوارئ"</string> </resources> diff --git a/PermissionController/res/values-ar-watch/strings.xml b/PermissionController/res/values-ar-watch/strings.xml index c49e30aa6..fe1bb345b 100644 --- a/PermissionController/res/values-ar-watch/strings.xml +++ b/PermissionController/res/values-ar-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"لا يمكن التغيير"</string> <string name="generic_yes" msgid="2489207724988649846">"نعم"</string> <string name="generic_cancel" msgid="2631708607129269698">"إلغاء"</string> + <string name="permission_access_always" msgid="2107115233573823032">"طوال الوقت"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"أثناء استخدام التطبيق"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"طوال الوقت"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"أثناء استخدام التطبيق"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"طوال الوقت"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"أثناء استخدام التطبيق"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"طوال الوقت"</string> </resources> diff --git a/PermissionController/res/values-ar/strings.xml b/PermissionController/res/values-ar/strings.xml index 47731ef8b..ec9a12c68 100644 --- a/PermissionController/res/values-ar/strings.xml +++ b/PermissionController/res/values-ar/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"كل الأذونات"</string> <string name="other_permissions" msgid="2901186127193849594">"إمكانات التطبيق الأخرى"</string> <string name="permission_request_title" msgid="8790310151025020126">"طلب الإذن"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"لا تتوافق إجراءات التثبيت/إلغاء التثبيت مع نظام Android Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"اختيار ما تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إليه"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"تمّ تحديث <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. وعليك اختيار ما تريد السماح لهذا التطبيق بالوصول إليه."</string> <string name="review_button_cancel" msgid="2191147944056548886">"إلغاء"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"عندما يكون الموقع الجغرافي الدقيق غير مفعّل، يمكن للتطبيقات الوصول إلى الموقع الجغرافي التقريبي."</string> <string name="app_permission_title" msgid="2090897901051370711">"إذن <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"منح هذا التطبيق الإذن بالوصول إلى <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"إذن \"<xliff:g id="PERM">%1$s</xliff:g>\" لهذا التطبيق على \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"الاطّلاع على جميع أذونات تطبيق \"<xliff:g id="APP">%1$s</xliff:g>\""</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"الاطّلاع على جميع التطبيقات التي لديها هذا الإذن"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"عرض أذونات استخدام ميكروفون \"مساعد Google\""</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"إزالة الأذونات في حال عدم استخدام التطبيق"</string> <string name="unused_apps_label" msgid="2595428768404901064">"إزالة الأذونات وإخلاء مساحة"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"إيقاف نشاط التطبيق مؤقتًا عند عدم استخدامه"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"إدارة التطبيق في حال عدم استخدامه"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"إزالة الأذونات وحذف الملفات المؤقتة وإيقاف الإشعارات"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"إزالة الأذونات وحذف الملفات المؤقتة وإيقاف الإشعارات وأرشفة التطبيق"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"لحماية بياناتك، ستتم إزالة أذونات هذا التطبيق إذا لم يتم استخدامه لبضعة أشهر."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"لحماية بياناتك، إذا لم يتم استخدام التطبيق لبضعة أشهر، ستتم إزالة الأذونات التالية: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"لحماية بياناتك، تمت إزالة الأذونات من هذه التطبيقات التي لم تستخدمها منذ بضعة أشهر."</string> @@ -234,7 +235,7 @@ <string name="permission_description_summary_call_log" msgid="7321437186317577624">"يمكن للتطبيقات التي تحصل على هذا الإذن قراءة بيانات سجلّ مكالمات الهاتف وتعديلها."</string> <string name="permission_description_summary_camera" msgid="108004375101882069">"يمكن للتطبيقات التي تملك هذا الإذن التقاط صور وتسجيل فيديوهات."</string> <string name="permission_description_summary_contacts" msgid="2337798886460408996">"يمكن للتطبيقات التي لديها هذا الإذن الوصول إلى جهات الاتصال الخاصة بك."</string> - <string name="permission_description_summary_location" msgid="2817531799933480694">"يمكن للتطبيقات التي لديها هذا الإذن الوصول إلى الموقع الجغرافي لهذا الجهاز."</string> + <string name="permission_description_summary_location" msgid="2817531799933480694">"يمكن للتطبيقات التي لديها هذا الإذن الوصول إلى الموقع الجغرافي لهذا الجهاز"</string> <string name="permission_description_summary_nearby_devices" msgid="8269183818275073741">"تتمكن التطبيقات التي لديها هذا الإذن من العثور على الأجهزة المجاورة والربط بها وتحديد موضعها النسبي."</string> <string name="permission_description_summary_microphone" msgid="630834800308329907">"يمكن للتطبيقات التي لديها هذا الإذن تسجيل الصوت."</string> <string name="permission_description_summary_phone" msgid="4515277217435233619">"يمكن للتطبيقات التي لديها هذا الإذن إجراء مكالمات هاتفية وإدارتها."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"التطبيقات المسموح لها بإدارة كل الملفات"</string> <string name="ask_header" msgid="2633816846459944376">"الطلب في كل مرة"</string> <string name="denied_header" msgid="903209608358177654">"التطبيقات غير المسموح لها"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"\"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>\" على \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"الاطّلاع على تطبيقات أكثر يمكنها الوصول إلى كل الملفات"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{يوم واحد}zero{# يوم}two{يومان}few{# أيام}many{# يومًا}other{# يوم}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{ساعة واحدة}zero{# ساعة}two{ساعتان}few{# ساعات}many{# ساعةً}other{# ساعة}}"</string> @@ -317,7 +319,7 @@ <string name="permission_subtitle_media_only" msgid="8917869683764720717">"الوسائط"</string> <string name="permission_subtitle_all_files" msgid="4982613338298067862">"كل الملفات"</string> <string name="permission_subtitle_background" msgid="8916750995309083180">"مسموح بالوصول إليه طوال الوقت"</string> - <string name="app_perms_24h_access" msgid="99069906850627181">"تم استخدامه آخر مرة في <xliff:g id="TIME_DATE">%1$s</xliff:g>."</string> + <string name="app_perms_24h_access" msgid="99069906850627181">"تم استخدامه آخر مرة في <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> <string name="app_perms_24h_access_yest" msgid="5411926024794555022">"تم استخدامه آخر مرة أمس في <xliff:g id="TIME_DATE">%1$s</xliff:g>."</string> <string name="app_perms_7d_access" msgid="4945055548894683751">"تم الوصول آخر مرة بتاريخ <xliff:g id="TIME_DATE_0">%1$s</xliff:g> في <xliff:g id="TIME_DATE_1">%2$s</xliff:g>."</string> <string name="app_perms_content_provider_24h" msgid="1055526027667508972">"تم الوصول للأذونات في آخر 24 ساعة."</string> @@ -337,7 +339,7 @@ <string name="app_perms_7d_access_all_files" msgid="8246193786397635824">"تم الوصول آخر مرة بتاريخ <xliff:g id="TIME_DATE_0">%1$s</xliff:g> في <xliff:g id="TIME_DATE_1">%2$s</xliff:g> • جميع الملفات"</string> <string name="app_perms_content_provider_24h_all_files" msgid="573104317727770850">"تم الوصول في آخر 24 ساعة • كل الملفات"</string> <string name="app_perms_content_provider_7d_all_files" msgid="7962416229708835558">"تم الوصول في آخر 7 أيام • جميع الملفات"</string> - <string name="no_permissions_allowed" msgid="6081976856354669209">"لم يتم منح أي أذونات."</string> + <string name="no_permissions_allowed" msgid="6081976856354669209">"لم يتم منح أي أذونات"</string> <string name="no_permissions_denied" msgid="8159923922804043282">"لم يتم رفض أي أذونات."</string> <string name="no_apps_allowed" msgid="7718822655254468631">"لم يتم السماح لأي تطبيقات."</string> <string name="no_apps_allowed_full" msgid="8011716991498934104">"ما من تطبيقات تم منحها إذن الوصول إلى جميع الملفات."</string> @@ -351,7 +353,7 @@ <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"يمكن لهذه التطبيقات عرض شاشتك وإجراءاتك ومدخلاتك وتنفيذ الإجراءات والتحكم في العرض."</string> <string name="role_assistant_label" msgid="4727586018198208128">"تطبيق المساعد الرقمي التلقائي"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"تطبيق المساعد الرقمي"</string> - <string name="role_assistant_description" msgid="6622458130459922952">"بإمكان التطبيقات المساعِدة مساعدتك استنادًا إلى المعلومات على الشاشة التي تشاهدها. وتتوافق بعض التطبيقات مع كل من خدمة المشغّل وخدمة الإدخال الصوتي لتوفير مساعدة متكاملة لك."</string> + <string name="role_assistant_description" msgid="6622458130459922952">"بإمكان التطبيقات المساعِدة مساعدك استنادًا إلى المعلومات التي تظهر على شاشتك. وتعمل بعض التطبيقات مع كل من خدمة المشغّل وخدمة الإدخال الصوتي لتوفير مساعدة متكاملة لك."</string> <string name="role_browser_label" msgid="2877796144554070207">"تطبيق المتصفّح التلقائي"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"تطبيق المتصفح"</string> <string name="role_browser_description" msgid="3465253637499842671">"التطبيقات التي تتيح إمكانية الوصول إلى الإنترنت وتعرض روابط تنقر عليها"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"تطبيق تدوين الملاحظات"</string> <string name="role_notes_description" msgid="8496852798616883551">"التطبيقات التي تتيح لك تدوين ملاحظات على جهازك"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ملاحظات"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"تطبيق المحفظة التلقائي"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"تطبيق المحفظة"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"يمكن أن تخزِّن تطبيقات المحافِظ معلومات بطاقات الائتمان وبطاقات الولاء والمفاتيح الرقمية للسيارات وغيرها من المعلومات للمساعدة في إدارة أنواع المعاملات المختلفة."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"هل تريد ضبط \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" على أنّه تطبيق المحفظة التلقائي؟"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ما مِن أذونات مطلوبة."</string> <string name="request_role_current_default" msgid="738722892438247184">"التطبيق التلقائي الحالي"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"لا تسألني مرة أخرى."</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ضبط كتطبيق تلقائي"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"يحتاج هذا التطبيق إلى تسجيل الصوت طوال الوقت، حتى عند عدم استخدامك للتطبيق. يمكنك "<annotation id="link">"السماح بذلك في الإعدادات"</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"هل تريد السماح للتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى بيانات نشاطك البدني؟"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى بيانات نشاطك البدني على جهاز <b><xliff:g id="DEVICE">%2$s</xliff:g></b>؟"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالتقاط صور وتسجيل فيديوهات؟"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"هل يمكنك السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالتقاط صور وتسجيل فيديوهات؟"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالتقاط الصور وتسجيل الفيديوهات على جهاز <b><xliff:g id="DEVICE">%2$s</xliff:g></b>؟"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"لن يتمكن هذا التطبيق من التقاط صور وتسجيل فيديوهات إلا عندما يكون قيد الاستخدام"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالتقاط صور وتسجيل فيديوهات؟"</string> @@ -545,7 +552,7 @@ <string name="exempt_info_label" msgid="6286190981253476699">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> محمي بواسطة Android. لأن بياناتك تتم معالجتها على هذا الجهاز، لا يظهر استخدام إذن هذا التطبيق في لوحة بيانات الخصوصية."</string> <string name="blocked_camera_title" msgid="1128510551791284384">"كاميرا الجهاز محظورة"</string> <string name="blocked_microphone_title" msgid="1631517143648232585">"ميكروفون الجهاز محظور"</string> - <string name="blocked_location_title" msgid="2005608279812892383">"ميزة الموقع الجغرافي للجهاز غير مفعّلة."</string> + <string name="blocked_location_title" msgid="2005608279812892383">"ميزة الموقع الجغرافي للجهاز غير مفعّلة"</string> <string name="blocked_sensor_summary" msgid="4443707628305027375">"للتطبيقات والخدمات"</string> <string name="blocked_mic_summary" msgid="8960466941528458347">"لا يزال يمكن مشاركة بيانات الميكروفون عند الاتصال برقم طوارئ."</string> <string name="blocked_sensor_button_label" msgid="6742092634984289658">"تغيير"</string> @@ -609,7 +616,7 @@ <string name="camera_toggle_title" msgid="1251201397431837666">"الوصول إلى الكاميرا"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"الوصول إلى الميكروفون"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"للتطبيقات والخدمات"</string> - <string name="mic_toggle_description" msgid="9163104307990677157">"بالنسبة للتطبيقات والخدمات. إذا كان هذا الخيار غير مفعّل، قد يظل بالإمكان مشاركة بيانات الميكروفون عند الاتصال برقم طوارئ."</string> + <string name="mic_toggle_description" msgid="9163104307990677157">"للتطبيقات والخدمات. إذا كان هذا الخيار غير مفعّل، قد تتم مشاركة بيانات الميكروفون عند الاتصال برقم طوارئ"</string> <string name="location_settings_subtitle" msgid="2328360561197430695">"عرض التطبيقات والخدمات التي يمكنها الوصول إلى الموقع الجغرافي"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"عرض إشعار عند الوصول إلى الحافظة"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"عرض رسالة عندما يصل التطبيق إلى نص أو صور أو محتوى آخر تم نسخه"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"تعديلات مشاركة البيانات"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"غيّرت بعض التطبيقات الطريقة التي قد تشارك بها بيانات موقعك الجغرافي."</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"الإعدادات"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"آخر استخدام للإذن: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"آخر استخدام للإذن أمس: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"آخر استخدام للإذن في <xliff:g id="TIME_DATE_0">%1$s</xliff:g>: <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"كلمة المرور الصالحة لمرة واحدة هي 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"الإعداد محظور"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"للحفاظ على أمانك، هذا الإعداد غير متوفِّر حاليًا."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"تم منع التطبيق من الوصول إلى <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"طلب التطبيق أحد أذونات الوصول إلى المعلومات الحساسة، ما قد يعرّض معلوماتك الشخصية والمالية للخطر.<xliff:g id="ID_1"><br><br></xliff:g>من المحتمل ألا يعمل التطبيق بشكل صحيح إذا لم يحصل على هذا الإذن المقيَّد. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>مزيد من المعلومات حول كيفية منح الأذونات</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"لم يتم السماح للتطبيق بأن يُستخدَم كـ <xliff:g id="ROLE_NAME">%1$s</xliff:g> تلقائيًا"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"طلب التطبيق أذونات الوصول إلى المعلومات الحساسة، ما قد يعرّض معلوماتك الشخصية والمالية للخطر.<xliff:g id="ID_1"><br><br></xliff:g>من المحتمل ألا يعمل التطبيق بشكل صحيح إذا لم يحصل على هذه الأذونات المقيَّدة. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>مزيد من المعلومات حول كيفية منح الأذونات</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"تم منع التطبيق من الوصول"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"إذا منحت التطبيق هذا الإذن، يمكن أن تتعرّض معلوماتك الشخصية والمالية للخطر.<xliff:g id="ID_1"><br><br></xliff:g>من المحتمل ألا يعمل التطبيق بشكل صحيح إذا لم يحصل على هذا الإذن المقيَّد. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>مزيد من المعلومات حول كيفية منح الأذونات</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"مزيد من المعلومات"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"حسنًا"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"تم إلغاء طلب الحصول على الإذن"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"يطلب هذا التطبيق الحصول على أذونات إضافية، ولكن لا يمكن منح أذونات في جلسة بث. امنح الإذن على هاتفك أولاً."</string> </resources> diff --git a/PermissionController/res/values-as-v34/strings.xml b/PermissionController/res/values-as-v34/strings.xml index 219f79370..e0acecb4f 100644 --- a/PermissionController/res/values-as-v34/strings.xml +++ b/PermissionController/res/values-as-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"স্বাস্থ্য সম্পৰ্কীয় ডেটালৈ এপৰ এক্সেছ পৰিচালনা কৰক"</string> <string name="location_settings" msgid="8863940440881290182">"অৱস্থানৰ এক্সেছ"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"এপ্ আৰু সেৱাৰ বাবে। এই ছেটিংটো অফ হৈ থাকিলে, আপুনি কোনো জৰুৰীকালীন নম্বৰলৈ কল কৰিলে মাইক্ৰ’ফ’নৰ ডেটা তথাপি শ্বেয়াৰ কৰা হ’ব পাৰে"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"এপ্ আৰু সেৱাৰ বাবে"</string> </resources> diff --git a/PermissionController/res/values-as-watch/strings.xml b/PermissionController/res/values-as-watch/strings.xml index 314a08e71..ee41e21d6 100644 --- a/PermissionController/res/values-as-watch/strings.xml +++ b/PermissionController/res/values-as-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"সলনি কৰিব নোৱাৰি"</string> <string name="generic_yes" msgid="2489207724988649846">"হয়"</string> <string name="generic_cancel" msgid="2631708607129269698">"বাতিল কৰক"</string> + <string name="permission_access_always" msgid="2107115233573823032">"সকলো সময়তে"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"এপ্টো ব্যৱহাৰ কৰা সময়ত"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"সকলো সময়তে"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"এপ্টো ব্যৱহাৰ কৰা সময়ত"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"সকলো সময়তে"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"এপ্টো ব্যৱহাৰ কৰা সময়ত"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"সকলো সময়তে"</string> </resources> diff --git a/PermissionController/res/values-as/strings.xml b/PermissionController/res/values-as/strings.xml index 162b4a8ff..1a8eaaee7 100644 --- a/PermissionController/res/values-as/strings.xml +++ b/PermissionController/res/values-as/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"সকলো অনুমতি"</string> <string name="other_permissions" msgid="2901186127193849594">"অন্য এপৰ কার্যক্ষমতা"</string> <string name="permission_request_title" msgid="8790310151025020126">"অনুমতি বিচাৰি কৰা অনুৰোধ"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"ইনষ্টল/আনইনষ্টল কাৰ্য Wearত কৰিব নোৱাৰি।"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ক ক’ত এক্সেছ দিব লাগে বাছনি কৰক"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> আপডে’ট কৰা হৈছে। এই এপক ক’ত এক্সেছ দিব লাগে বাছনি কৰক।"</string> <string name="review_button_cancel" msgid="2191147944056548886">"বাতিল কৰক"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"সঠিক অৱস্থানটো অফ থাকিলে, এপে আপোনাৰ আনুমানিক অৱস্থান এক্সেছ কৰিব পাৰে"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>ৰ অনুমতি"</string> <string name="app_permission_header" msgid="2951363137032603806">"এই এপ্টোৰ বাবে <xliff:g id="PERM">%1$s</xliff:g>ৰ এক্সেছ"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>ত এই এপৰ <xliff:g id="PERM">%1$s</xliff:g>ৰ এক্সেছ"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"আটাইবোৰ <xliff:g id="APP">%1$s</xliff:g> অনুমতি চাওক"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"এই অনুমতি থকা আটাইবোৰ এপ্ চাওক"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"সহায়ক মাইক্ৰ’ফ’নৰ ব্যৱহাৰ দেখুৱাওক"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"যদি এপ্টো ব্যৱহাৰ কৰা নাই অনুমতিসমূহ আঁতৰাওক"</string> <string name="unused_apps_label" msgid="2595428768404901064">"অনুমতি আঁতৰাওক আৰু ঠাই খালী কৰক"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"অব্যৱহৃত হৈ থাকিলে এপৰ কাৰ্যকলাপ পজ কৰক"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"যদি ব্যৱহাৰ হোৱা নাই এপ্টো পৰিচালনা কৰক"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"অনুমতি আঁতৰাওক, অস্থায়ী ফাইল মচক আৰু জাননী বন্ধ কৰক"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"অনুমতি আঁতৰাওক, অস্থায়ী ফাইল মচক, জাননী বন্ধ কৰক আৰু এপ্টো আৰ্কাইভ কৰক"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"আপোনাৰ ডেটা সুৰক্ষিত কৰিবলৈ এই এপ্টো কেইমাহমান ব্যৱহাৰ নকৰিলে এইটোৰ বাবে থকা অনুমতিসমূহ আঁতৰোৱা হ\'ব।"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"আপোনাৰ ডেটা সুৰক্ষিত কৰিবলৈ এই এপ্টো কেইমাহমান ব্যৱহাৰ নকৰিলে তলত উল্লেখ কৰা অনুমতিসমূহ আঁতৰোৱা হ\'ব: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"আপোনাৰ ডেটা সুৰক্ষিত কৰিবলৈ আপুনি কেইমাহমান ব্যৱহাৰ নকৰা এপ্সমূহৰ পৰা অনুমতিসমূহ আঁতৰোৱা হ\'ব।"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"আটাইবোৰ ফাইল পৰিচালনা কৰিবলৈ অনুমতি আছে"</string> <string name="ask_header" msgid="2633816846459944376">"প্ৰতিবাৰতে সোধক"</string> <string name="denied_header" msgid="903209608358177654">"অনুমতি নাই"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>ত <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"আটাইবোৰ ফাইল এক্সেছ কৰিব পৰা অধিক এপ্ চাওক"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{১ দিন}one{# দিন}other{# দিন}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ঘণ্টা}one{# ঘণ্টা}other{# ঘণ্টা}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"টোকা লোৱা এপ্"</string> <string name="role_notes_description" msgid="8496852798616883551">"আপোনাক আপোনাৰ ডিভাইচত টোকা ল’বলৈ দিয়া এপ্সমূহ"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"টোকা"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ডিফ’ল্ট Wallet এপ্"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet এপ্"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Wallet এপে বিভিন্ন ধৰণৰ লেনদেনত সহায় কৰিবলৈ আপোনাৰ ক্ৰেডিট আৰু লয়েল্টী কাৰ্ড, গাড়ীৰ চাবি আৰু আন বস্তু ষ্ট’ৰ কৰিব পাৰে।"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক আপোনাৰ ডিফ’ল্ট Wallet এপ্ হিচাপে ছেট কৰিবনে?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"কোনো অনুমতিৰ প্ৰয়োজন নাই"</string> <string name="request_role_current_default" msgid="738722892438247184">"বৰ্তমানৰ ডিফ’ল্ট"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"পুনৰায় নুসুধিব"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ডিফ’ল্ট ৰূপে ছেট কৰক"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ডেটা শ্বেয়াৰ কৰা সম্পৰ্কীয় আপডে’ট"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"কিছুমান এপে আপোনাৰ অৱস্থানৰ ডেটা শ্বেয়াৰ কৰিব পৰাৰ ধৰণসমূহ সলনি কৰিছে"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ছেটিং"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>ত এক্সেছ কৰিছিল"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"কালি <xliff:g id="TIME_DATE">%1$s</xliff:g>ত এক্সেছ কৰিছিল"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>ত এক্সেছ কৰিছিল"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"আপোনাৰ এবাৰ ব্যৱহাৰযোগ্য পাছৱর্ড হৈছে ১৩২৪৩৫"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"প্ৰতিবন্ধিত ছেটিং"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"আপোনাৰ সুৰক্ষাৰ বাবে, এই ছেটিংটো বৰ্তমান উপলব্ধ নহয়।"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"এপ্টোক <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>ৰ এক্সেছ প্ৰত্যাখ্যান কৰা হৈছে"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"এপ্টোৱে সংবেদনশীল অনুমতি এক্সেছ কৰিবলৈ অনুৰোধ কৰিছে, যিটোৱে আপোনাৰ ব্যক্তিগত আৰু বিত্তীয় তথ্য বিপদাপন্ন কৰিব পাৰে।<xliff:g id="ID_1"><br><br></xliff:g>এপ্টোৱে এই প্ৰতিবন্ধিত অনুমতিটোৰ অবিহনে সঠিককৈ কাম নকৰাটো সম্ভৱ হ’ব পাৰে। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>কেনেকৈ এক্সেছৰ অনুমতি দিব লাগে জানক</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"এপ্টোক ডিফ’ল্ট <xliff:g id="ROLE_NAME">%1$s</xliff:g>ৰ এক্সেছ প্ৰত্যাখ্যান কৰা হৈছে"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"এপ্টোৱে সংবেদনশীল অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুৰোধ কৰিছে, যিটোৱে আপোনাৰ ব্যক্তিগত আৰু বিত্তীয় তথ্য বিপদাপন্ন কৰিব পাৰে।<xliff:g id="ID_1"><br><br></xliff:g>এপ্টোৱে এই প্ৰতিবন্ধিত অনুমতিসমূহৰ অবিহনে সঠিককৈ কাম নকৰাটো সম্ভৱ হ’ব পাৰে। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>কেনেকৈ এক্সেছৰ অনুমতি দিব লাগে জানক</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"এপ্টোক এক্সেছ প্ৰত্যাখ্যান কৰা হৈছে"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"এই অনুমতিটোৰ এক্সেছ প্ৰদান কৰাটোৱে আপোনাৰ ব্যক্তিগত আৰু বিত্তীয় তথ্য বিপদাপন্ন কৰিব পাৰে।<xliff:g id="ID_1"><br><br></xliff:g>এপ্টোৱে এই প্ৰতিবন্ধিত অনুমতিটোৰ অবিহনে সঠিককৈ কাম নকৰাটো সম্ভৱ হ’ব পাৰে। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>কেনেকৈ এক্সেছৰ অনুমতি দিব লাগে জানক</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"অধিক জানক"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ঠিক আছে"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"অনুমতিৰ অনুৰোধ অৱদমন কৰা হৈছে"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"এই এপ্টোৱে অতিৰিক্ত অনুমতিৰ বাবে অনুৰোধ কৰিছে, কিন্তু ষ্ট্ৰীমিং ছেশ্বনত অনুমতি দিব নোৱাৰি। আপোনাৰ ফ’নটোত প্ৰথমে অনুমতি দিয়ক।"</string> </resources> diff --git a/PermissionController/res/values-az-v34/strings.xml b/PermissionController/res/values-az-v34/strings.xml index 7e403dadc..834a2a002 100644 --- a/PermissionController/res/values-az-v34/strings.xml +++ b/PermissionController/res/values-az-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Tətbiqin sağlamlıq datasına girişini idarə edin"</string> <string name="location_settings" msgid="8863940440881290182">"Məkana giriş"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Tətbiq və xidmətlər üçün. Bu ayar deaktivdirsə, təcili nömrəyə zəng etdikdə mikrofon datası yenə də paylaşıla bilər"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Tətbiq və xidmətlər üçün"</string> </resources> diff --git a/PermissionController/res/values-az-watch/strings.xml b/PermissionController/res/values-az-watch/strings.xml index 1b4273903..92d8c0e5f 100644 --- a/PermissionController/res/values-az-watch/strings.xml +++ b/PermissionController/res/values-az-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Dəyişdirilmədi"</string> <string name="generic_yes" msgid="2489207724988649846">"Bəli"</string> <string name="generic_cancel" msgid="2631708607129269698">"Ləğv edin"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Hər zaman"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Tətbiq istifadə edərkən"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Hər zaman"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Tətbiq istifadə edərkən"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Hər zaman"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Tətbiq istifadə edərkən"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Hər zaman"</string> </resources> diff --git a/PermissionController/res/values-az/strings.xml b/PermissionController/res/values-az/strings.xml index 3d854cb29..089a22aed 100644 --- a/PermissionController/res/values-az/strings.xml +++ b/PermissionController/res/values-az/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Bütün icazələr"</string> <string name="other_permissions" msgid="2901186127193849594">"Digər tətbiq imkanları"</string> <string name="permission_request_title" msgid="8790310151025020126">"İcazə sorğusu"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Yükləmə/Sistemdən silmə fəaliyyətləri Wear\'də dəstəklənmir."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqinin daxil olacağı elementləri seçin"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> güncəlləndi. Bu tətbiqin daxil olacağı elementləri seçin."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Ləğv edin"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Məkan dəqiq aşkarlanmadıqda tətbiqlər məkanı təxmini müəyyən edir"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> üçün icazə"</string> <string name="app_permission_header" msgid="2951363137032603806">"Tətbiqə <xliff:g id="PERM">%1$s</xliff:g> icazəsi"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazında bu tətbiq üçün <xliff:g id="PERM">%1$s</xliff:g> girişi"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Bütün <xliff:g id="APP">%1$s</xliff:g> icazələrinə baxın"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Bu icazəyə sahib olan bütün tətbiqlərə baxın"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistent üçün mikrofon istifadəsini göstərin"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Tətbiq işlənməyəndə icazə ləğv edilsin"</string> <string name="unused_apps_label" msgid="2595428768404901064">"İcazələri silin və yer boşaldın"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"İstifadə edilmədikdə tətbiq fəaliyyətini durdurun"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"İstifadə edilmədikdə tətbiqi idarə edin"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"İcazələri silin, müvəqqəti faylları silin və bildirişləri dayandırın"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"İcazələri, müvəqqəti faylları silin, bildirişləri dayandırın və tətbiqi arxivə atın"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Bir neçə ay istifadə etmədiyiniz tətbiqlərdən icazələr datanızın qorunması məqsədilə silinib."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Bir neçə ay istifadə etmədiyiniz tətbiqlərdən icazələr datanızın qorunması məqsədilə silinib: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Bir neçə ay istifadə etmədiyiniz tətbiqlərdən icazələr datanızın qorunması məqsədilə silinib."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Bütün fayllara girişi olanlar"</string> <string name="ask_header" msgid="2633816846459944376">"Həmişə soruşulsun"</string> <string name="denied_header" msgid="903209608358177654">"İcazə verilməyib"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazında <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Bütün fayllara giriş edə bilən digər tətbiqlərə baxın"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 gün}other{# gün}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# saat}other{# saat}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Qeyd tətbiqi"</string> <string name="role_notes_description" msgid="8496852798616883551">"Cihazınızda qeydlər aparmağa imkan verən tətbiqlər"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"qeydlər"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Defolt pulqabı tətbiqi"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Pulqabı tətbiqi"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Pulqabı tətbiqləri müxtəlif əməliyyat formaları ilə bağlı kömək etmək üçün kredit və sadiqlik kartlarını, avtomobil açarlarını və digər əşyaları saxlaya bilər."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> defolt pulqabı tətbiqi kimi ayarlansın?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"İcazəyə ehtiyac yoxdur"</string> <string name="request_role_current_default" msgid="738722892438247184">"Cari defolt"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Bir daha soruşmayın"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Defolt olaraq seçin"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Data paylaşma yenilikləri"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Bəzi tətbiqlər məkan datasını paylaşma üsulunu dəyişib"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Ayarlar"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Daxil olunub: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Daxil olunub: dünən <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Daxil olunub: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Birdəfəlik parol: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Məhdudlaşdırılmış ayar"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Güvənlik üçün bu ayar əlçatan deyil."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Tətbiqə <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> icazəsinə giriş verilmədi"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Tətbiq şəxsi və maliyyə məlumatlarınızı riskə ata biləcək həssas məlumat icazəsinə giriş istədi.<xliff:g id="ID_1"><br><br></xliff:g>Bu məhdud icazə olmadan tətbiq düzgün işləməyə bilər. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Girişə icazə vermək haqqında ətraflı</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Tətbiqə defolt <xliff:g id="ROLE_NAME">%1$s</xliff:g> roluna giriş verilmədi"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Tətbiq şəxsi və maliyyə məlumatlarınızı riskə ata biləcək həssas məlumat icazələrinə giriş istədi.<xliff:g id="ID_1"><br><br></xliff:g>Bu məhdud icazələr olmadan tətbiq düzgün işləməyə bilər. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Girişə icazə vermək haqqında ətraflı</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Tətbiqə giriş verilmədi"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Bu icazəyə giriş şəxsi və maliyyə məlumatlarını riskə ata bilər.<xliff:g id="ID_1"><br><br></xliff:g>Bu məhdud icazə olmadan tətbiq düzgün işləməyə bilər. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Girişə icazə vermək haqqında ətraflı</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Ətraflı məlumat"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"İcazə sorğusu dayandırıldı"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Bu tətbiqə əlavə icazələr lazımdır, lakin yayım sessiyasında icazə vermək olmur. Əvvəlcə telefonda icazə verin."</string> </resources> diff --git a/PermissionController/res/values-b+sr+Latn-v34/strings.xml b/PermissionController/res/values-b+sr+Latn-v34/strings.xml index d5bf45128..e4af6c3e6 100644 --- a/PermissionController/res/values-b+sr+Latn-v34/strings.xml +++ b/PermissionController/res/values-b+sr+Latn-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Upravljajte pristupom aplikacija podacima o zdravlju"</string> <string name="location_settings" msgid="8863940440881290182">"Pristup lokaciji"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Za aplikacije i usluge. Ako je ovo podešavanje isključeno, podaci mikrofona mogu i dalje da se dele kada pozovete broj za hitne slučajeve"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Za aplikacije i usluge"</string> </resources> diff --git a/PermissionController/res/values-b+sr+Latn-watch/strings.xml b/PermissionController/res/values-b+sr+Latn-watch/strings.xml index 673a26286..f4b6e53bb 100644 --- a/PermissionController/res/values-b+sr+Latn-watch/strings.xml +++ b/PermissionController/res/values-b+sr+Latn-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Ne može da se promeni"</string> <string name="generic_yes" msgid="2489207724988649846">"Da"</string> <string name="generic_cancel" msgid="2631708607129269698">"Otkaži"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Sve vreme"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Pri korišćenju aplikacije"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Sve vreme"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Pri korišćenju aplikacije"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Sve vreme"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Pri korišćenju aplikacije"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Sve vreme"</string> </resources> diff --git a/PermissionController/res/values-b+sr+Latn/strings.xml b/PermissionController/res/values-b+sr+Latn/strings.xml index 3f109b756..fab24c485 100644 --- a/PermissionController/res/values-b+sr+Latn/strings.xml +++ b/PermissionController/res/values-b+sr+Latn/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Sve dozvole"</string> <string name="other_permissions" msgid="2901186127193849594">"Ostale mogućnosti aplikacije"</string> <string name="permission_request_title" msgid="8790310151025020126">"Zahtev za dozvolu"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Radnje Instaliraj/Deinstaliraj nisu podržane u Wear-u."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Izaberite čemu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> može da pristupa"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> je ažurirana. Izaberite čemu ova aplikacija može da pristupa."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Otkaži"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Aplikacije mogu da pristupaju vašoj približnoj lokaciji kada je precizna isključena"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> - dozvola"</string> <string name="app_permission_header" msgid="2951363137032603806">"Pristup ove aplikacije funkciji „<xliff:g id="PERM">%1$s</xliff:g>“"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Ova aplikacija ima pristup za: <xliff:g id="PERM">%1$s</xliff:g> na uređaju <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Prikaži sve dozvole za: <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Prikaži sve aplikacije sa ovom dozvolom"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Prikaži kako Pomoćnik koristi mikrofon"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Ukloni dozvole ako se aplikacija ne koristi"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Ukloni dozvole i oslobodi prostor"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pauziraj aktivnosti ako se ne koristi"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Upravljajte aplikacijom ako se ne koristi"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Uklonite dozvole, izbrišite privremene fajlove i zaustavite obaveštenja"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Uklonite dozvole, izbrišite privremene fajlove, zaustavite obaveštenja i arhivirajte aplikaciju"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Radi zaštite podataka, dozvole za ovu aplikaciju se uklanjaju ako se aplikacija ne koristi par meseci."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Radi zaštite podataka, sledeće dozvole se uklanjaju ako se aplikacija ne koristi par meseci: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Radi zaštite podataka, dozvole su uklonjene iz aplikacija koje niste koristili par meseci."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Imaju dozvolu za upravljanje svim datotekama"</string> <string name="ask_header" msgid="2633816846459944376">"Pitaj svaki put"</string> <string name="denied_header" msgid="903209608358177654">"Nije dozvoljeno"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> na uređaju <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Prikaži još aplikacija sa pristupom svim fajlovima"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dan}one{# dan}few{# dana}other{# dana}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# sat}one{# sat}few{# sata}other{# sati}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikacija za beleške"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikacije koje vam omogućavaju da pravite beleške na uređaju"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"beleške"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Podrazumevana aplikacija Novčanik"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikacija Novčanik"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplikacije Novčanik mogu da čuvaju vaše kreditne kartice i kartice lojalnosti, ključeve od automobila i druge stvari kako bi vam pomogli pri različitim transakcijama."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Želite da podesite <xliff:g id="APP_NAME">%1$s</xliff:g> kao podrazumevanu aplikaciju Novčanik?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nije potrebna nijedna dozvola"</string> <string name="request_role_current_default" msgid="738722892438247184">"Trenutno podrazumevana"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ne pitaj ponovo"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Podesi kao podrazum."</string> @@ -438,7 +445,7 @@ <string name="no_special_app_access" msgid="6950277571805106247">"Nema posebnog pristupa apl."</string> <string name="special_app_access_no_apps" msgid="4102911722787886970">"Nema aplikacija"</string> <string name="home_missing_work_profile_support" msgid="1756855847669387977">"Ne podržava poslovni profil"</string> - <string name="encryption_unaware_confirmation_message" msgid="8274491794636402484">"Napomena: Ako restartujete uređaj i podesili ste zaključavanje ekrana, ova aplikacija ne može da se pokrene dok ne otključate uređaj."</string> + <string name="encryption_unaware_confirmation_message" msgid="8274491794636402484">"Napomena: Ako restartujete uređaj i podesili ste otključavanje ekrana, ova aplikacija ne može da se pokrene dok ne otključate uređaj."</string> <string name="assistant_confirmation_message" msgid="7476540402884416212">"Pomoćnik će moći da čita informacije o aplikacijama koje se koriste u sistemu, uključujući informacije vidljive na ekranu ili kojima može da se pristupa u okviru aplikacija."</string> <string name="incident_report_channel_name" msgid="3144954065936288440">"Deljenje podataka o otklanjanju grešaka"</string> <string name="incident_report_notification_title" msgid="4635984625656519773">"Delite detaljne podatke za otklanjanje grešaka?"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"Ova aplikacija želi da snima zvuk sve vreme, čak i kada ne koristite aplikaciju. "<annotation id="link">"Dozvolite u podešavanjima."</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"Želite li da dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa fizičkim aktivnostima?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"Dozvoljavate da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa podacima o fizičkim aktivnostima na uređaju <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"Želite da dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> snima slike i video snimke?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"Želite da dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> snima slike i video?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"Dozvolićete da aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> snima slike i video snimke na uređaju <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"Aplikacija će moći da snima slike i video snimke samo dok koristite aplikaciju"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"Želite da dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> snima slike i video snimke?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Ažuriranja za deljenje podataka"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Neke aplikacije su promenile način na koji mogu da dele podatke o lokaciji"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Podešavanja"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Pristupano: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Pristupano juče: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Pristupano: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Jednokratna lozinka je 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ograničeno podešavanje"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Ovo podešavanje je trenutno nedostupno radi vaše bezbednosti."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikaciji nije dozvoljen pristup dozvoli: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikacija je zatražila pristup osetljivoj dozvoli, što može da ugrozi bezbednost ličnih i finansijskih podataka.<xliff:g id="ID_1"><br><br></xliff:g>Aplikacija možda neće raditi ispravno bez ove ograničene dozvole. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako da dozvolite pristup</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikaciji nije dozvoljen pristup da postane podrazumevana: <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikacija je zatražila pristup osetljivim dozvolama, što može da ugrozi bezbednost ličnih i finansijskih podataka.<xliff:g id="ID_1"><br><br></xliff:g>Aplikacija možda neće raditi ispravno bez ovih ograničenih dozvola. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako da dozvolite pristup</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikaciji nije dozvoljen pristup"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Pristup ovoj dozvoli može da ugrozi bezbednost ličnih i finansijskih podataka.<xliff:g id="ID_1"><br><br></xliff:g>Aplikacija možda neće raditi ispravno bez ove ograničene dozvole. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako da dozvolite pristup</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Saznajte više"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Važi"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Zahtev za dozvolu je blokiran"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ova aplikacija zahteva dodatne dozvole, ali dozvole ne mogu da se daju u sesiji strimovanja. Prvo dajte dozvolu na telefonu."</string> </resources> diff --git a/PermissionController/res/values-be-v34/strings.xml b/PermissionController/res/values-be-v34/strings.xml index 330681ded..9d46314e6 100644 --- a/PermissionController/res/values-be-v34/strings.xml +++ b/PermissionController/res/values-be-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Кіруйце доступам праграм да даных пра здароўе"</string> <string name="location_settings" msgid="8863940440881290182">"Доступ да даных геалакацыі"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Для праграм і сэрвісаў. Нават калі гэта налада выключана, даныя з мікрафона будуць абагульвацца падчас выкліку нумара экстраннай службы"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Для праграм і сэрвісаў"</string> </resources> diff --git a/PermissionController/res/values-be-watch/strings.xml b/PermissionController/res/values-be-watch/strings.xml index 242f6306d..c237932f5 100644 --- a/PermissionController/res/values-be-watch/strings.xml +++ b/PermissionController/res/values-be-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Не ўдалося змяніць"</string> <string name="generic_yes" msgid="2489207724988649846">"Так"</string> <string name="generic_cancel" msgid="2631708607129269698">"Скасаваць"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Заўсёды"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Пры выкарыстанні праграмы"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Заўсёды"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Пры выкарыстанні праграмы"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Заўсёды"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Пры выкарыстанні праграмы"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Заўсёды"</string> </resources> diff --git a/PermissionController/res/values-be/strings.xml b/PermissionController/res/values-be/strings.xml index ef9983065..42ee653b7 100644 --- a/PermissionController/res/values-be/strings.xml +++ b/PermissionController/res/values-be/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Усе дазволы"</string> <string name="other_permissions" msgid="2901186127193849594">"Іншыя магчымасці праграмы"</string> <string name="permission_request_title" msgid="8790310151025020126">"Запыт дазволу"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Дзеянні па ўсталяванні або выдаленні не падтрымліваюцца на Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Выберыце, да чаго дазволіць доступ праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Праграма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> была абноўлена. Выберыце, да чаго ёй дазволіць доступ."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Скасаваць"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Калі вызначэнне дакладнага месцазнаходжання выключана, у праграм можа заставацца доступ да даных пра прыблізнае месцазнаходжанне"</string> <string name="app_permission_title" msgid="2090897901051370711">"Дазвол \"<xliff:g id="PERM">%1$s</xliff:g>\""</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: доступ для гэтай праграмы"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Дазвол \"<xliff:g id="PERM">%1$s</xliff:g>\" для гэтай праграмы на прыладзе \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Паказаць усе дазволы праграмы \"<xliff:g id="APP">%1$s</xliff:g>\""</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Паказаць усе праграмы з гэтым дазволам"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Паказваць выкарыстанне мікрафона памочнікам"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Выдаляць дазволы, калі праграма не выкарыстоўваецца"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Выдаліць дазволы і вызваліць месца"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Прыпыніць дзеянні ў неактыўнай праграме"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Кіраваць праграмай, якой не карыстаюцца"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Выдаліць дазволы, часовыя файлы і спыніць апавяшчэнні"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Выдаліць дазволы і часовыя файлы, спыніць адпраўку апавяшчэнняў і архіваваць праграму"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Калі праграма не выкарыстоўваецца на працягу некалькіх месяцаў, то ў мэтах абароны вашых даных з яе будуць выдалены дазволы."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Калі праграма не выкарыстоўваецца на працягу некалькіх месяцаў, у мэтах абароны вашых даных будуць выдалены наступныя дазволы: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"У мэтах абароны вашых даных выдалены дазволы для праграм, якія не выкарыстоўваліся некалькі месяцаў."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Дазволена кіраванне ўсімі файламі"</string> <string name="ask_header" msgid="2633816846459944376">"Заўсёды пытацца"</string> <string name="denied_header" msgid="903209608358177654">"Забароненыя"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"Група дазволаў \"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>\" на прыладзе \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Праглядзець іншыя праграмы, якія маюць доступ да ўсіх файлаў"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 дзень}one{# дзень}few{# дні}many{# дзён}other{# дня}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# гадзіна}one{# гадзіна}few{# гадзіны}many{# гадзін}other{# гадзіны}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Праграма для нататак"</string> <string name="role_notes_description" msgid="8496852798616883551">"Праграмы, якія дазваляюць рабіць нататкі на прыладзе"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"нататкі"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Стандартная праграма-кашалёк"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Праграма-кашалёк"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"У праграмах-кашальках можна захоўваць крэдытныя карткі, карткі лаяльнасці, ключы ад аўтамабіля і іншыя лічбавыя аб\'екты, што дае магчымасць ажыццяўляць розныя формы трансакцый."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Задаць у якасці стандартнай праграмы-кашалька праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Дазволы не патрэбныя"</string> <string name="request_role_current_default" msgid="738722892438247184">"Цяперашняя стандартная"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Больш не пытацца"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Зрабіць стандартнай"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Дазволіць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ да вашых кантактаў?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Дазволіць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ да кантактаў на прыладзе <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"Дазволіць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ да звестак пра месцазнаходжанне гэтай прылады?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Дазволіць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ да даных пра месцазнаходжанне прылады <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b>?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Дазволіць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ да даных пра месцазнаходжанне прылады <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Праграма будзе мець доступ да звестак пра месцазнаходжанне толькі падчас карыстання ёю"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Дазволіць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ да звестак пра месцазнаходжанне гэтай прылады?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Дазволіць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ да даных пра месцазнаходжанне прылады <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Змяненні ў абагульванні даных"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Для некаторых праграм спосаб абагульвання даных пра месцазнаходжанне змяніўся"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Налады"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Апошні раз доступ быў атрыманы ў <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Апошні раз доступ быў атрыманы ўчора ў <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Апошні раз доступ быў атрыманы ў <xliff:g id="TIME_DATE_1">%2$s</xliff:g> <xliff:g id="TIME_DATE_0">%1$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Ваш аднаразовы пароль: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Налада з абмежаваным доступам"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"У мэтах бяспекі гэта налада цяпер недаступная."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Праграме адмоўлена ў дазволе \"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>\""</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Праграма запытала дазвол на доступ да канфідэнцыяльнай інфармацыі. Калі вы яго дасце, ваша асабістая і фінансавая інфармацыя можа аказацца ў небяспецы.<xliff:g id="ID_1"><br><br></xliff:g>Магчыма, без гэтага абмежаванага дазволу праграма не будзе працаваць належным чынам. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Даведацца, як дазволіць доступ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Праграме адмоўлена ў дазволе стандартна выконваць наступную ролю: <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Праграма запытала дазволы на доступ да канфідэнцыяльнай інфармацыі. Калі вы іх дасце, ваша асабістая і фінансавая інфармацыя можа аказацца ў небяспецы.<xliff:g id="ID_1"><br><br></xliff:g>Магчыма, без гэтых абмежаваных дазволаў праграма не будзе працаваць належным чынам. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Даведацца, як дазволіць доступ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Праграме адмоўлена ў дазволе"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Калі вы дасце гэты дазвол, ваша асабістая і фінансавая інфармацыя можа аказацца ў небяспецы.<xliff:g id="ID_1"><br><br></xliff:g>Магчыма, без гэтага абмежаванага дазволу праграма не будзе працаваць належным чынам. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Даведацца, як дазволіць доступ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Даведацца больш"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Запыт дазволаў заблакіраваны"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Гэта праграма запытвае дадатковыя дазволы, якія немагчыма даць падчас трансляцыі. Спачатку дайце дазвол на тэлефоне."</string> </resources> diff --git a/PermissionController/res/values-bg-v34/strings.xml b/PermissionController/res/values-bg-v34/strings.xml index 33b3a52f0..6b7d5fea9 100644 --- a/PermissionController/res/values-bg-v34/strings.xml +++ b/PermissionController/res/values-bg-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Управлявайте достъпа на приложенията до данните за здравословното състояние"</string> <string name="location_settings" msgid="8863940440881290182">"Достъп до местоположението"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"За приложения и услуги. Ако тази настройка е изключена, данните от микрофона пак може да бъдат споделени, когато се обадите на номер за спешни случаи"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"За приложения и услуги"</string> </resources> diff --git a/PermissionController/res/values-bg-watch/strings.xml b/PermissionController/res/values-bg-watch/strings.xml index d09f250c4..48692ee7b 100644 --- a/PermissionController/res/values-bg-watch/strings.xml +++ b/PermissionController/res/values-bg-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Без промяна"</string> <string name="generic_yes" msgid="2489207724988649846">"Да"</string> <string name="generic_cancel" msgid="2631708607129269698">"Отказ"</string> + <string name="permission_access_always" msgid="2107115233573823032">"През цялото време"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"При използване на прилож."</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"През цялото време"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"При използване на прилож."</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"През цялото време"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"При използване на прилож."</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"През цялото време"</string> </resources> diff --git a/PermissionController/res/values-bg/strings.xml b/PermissionController/res/values-bg/strings.xml index fb5d670c7..f06e77444 100644 --- a/PermissionController/res/values-bg/strings.xml +++ b/PermissionController/res/values-bg/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Всички разрешения"</string> <string name="other_permissions" msgid="2901186127193849594">"Други възможности на приложението"</string> <string name="permission_request_title" msgid="8790310151025020126">"Заявка за разрешение"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Действията инсталиране и деинсталиране не се поддържат на устройства с Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Изберете до какво да има достъп <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Приложението <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> е актуализирано. Изберете до какво да има достъп."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Отказ"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Когато точното местоположение е изключено, приложенията могат да осъществяват достъп до приблизителното ви местоположение"</string> <string name="app_permission_title" msgid="2090897901051370711">"Разрешение за: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Достъп до „<xliff:g id="PERM">%1$s</xliff:g>“ за това приложение"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Достъп до <xliff:g id="PERM">%1$s</xliff:g> на <xliff:g id="DEVICE_NAME">%2$s</xliff:g> за това приложение"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Преглед на всички разрешения, предоставени за: <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Преглед на всички приложения с това разрешение"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Показване на употребата на микрофона за Асистент"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Премахване на разрешенията, ако приложението не се използва"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Премахване на разреш. и освоб. на място"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Поставяне на активн. в прилож. на пауза, ако не се ползва"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Управление на прилож., ако не се ползва"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Премахване на разрешенията, изтриване на временните файлове и спиране на известията"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Премахване на разрешенията, изтриване на временните файлове, спиране на известията и архивиране на приложението"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"За да защитим данните ви, разрешенията за това приложение ще бъдат премахнати, ако не го използвате няколко месеца."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"За да защитим данните ви, следните разрешения ще бъдат премахнати, ако не използвате приложението няколко месеца: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"За да защитим данните ви, премахнахме разрешенията за приложенията, които не сте използвали от няколко месеца."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"С разрешение за управление на всички файлове"</string> <string name="ask_header" msgid="2633816846459944376">"Запитване всеки път"</string> <string name="denied_header" msgid="903209608358177654">"Не е разрешено"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> на <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Вижте още приложения, които имат достъп до всички файлове"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ден}other{# дни}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# час}other{# часа}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Приложение за бележки"</string> <string name="role_notes_description" msgid="8496852798616883551">"Приложения, които ви дават възможност да си водите бележки на устройството си"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"бележки"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Основно приложение за портфейл"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Приложение за портфейл"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Приложенията за портфейли могат да съхраняват кредитни карти, карти за лоялност, ключове за автомобил и други неща, за да ви помагат при различни видове транзакции."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Да се зададе ли <xliff:g id="APP_NAME">%1$s</xliff:g> като основно приложение за портфейл?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Не са необходими разрешения"</string> <string name="request_role_current_default" msgid="738722892438247184">"Текущо стандартно приложение"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Без повторно питане"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Задаване"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Актуализации за споделянето на данни"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Някои приложения са променили как може да споделят данни за местоположението ви"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Настройки"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Осъществен достъп: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Осъществен достъп: вчера, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Осъществен достъп: <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Еднократната ви парола е 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ограничена настройка"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"От съображения за сигурност понастоящем тази настройка не е налице."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"На приложението бе отказан достъп до <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Приложението поиска разрешение за достъп до поверителни данни, което може да изложи на риск личната или финансовата ви информация.<xliff:g id="ID_1"><br><br></xliff:g>Възможно е приложението да не работи правилно без това ограничено разрешение. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Научете как да разрешите достъпа</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"На приложението бе забранено да изпълнява функциите на основно <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Приложението поиска разрешения за достъп до поверителни данни, които може да изложат на риск личната или финансовата ви информация.<xliff:g id="ID_1"><br><br></xliff:g>Възможно е приложението да не работи правилно без тези ограничени разрешения. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Научете как да разрешите достъпа</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"На приложението бе отказан достъп"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Достъпът до това разрешение може да изложи на риск личната и финансовата ви информация.<xliff:g id="ID_1"><br><br></xliff:g>Възможно е приложението да не работи правилно без това ограничено разрешение. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Научете как да разрешите достъпа</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Научете повече"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Заявката за разрешения е блокирана"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Това приложение изисква допълнителни разрешения, но те не могат да бъдат предоставени в сесия за поточно предаване. Първо ги предоставете на телефона си."</string> </resources> diff --git a/PermissionController/res/values-bn-v34/strings.xml b/PermissionController/res/values-bn-v34/strings.xml index c93980dd1..69ea5b8a9 100644 --- a/PermissionController/res/values-bn-v34/strings.xml +++ b/PermissionController/res/values-bn-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"স্বাস্থ্য সংক্রান্ত ডেটায় অ্যাপের অ্যাক্সেস ম্যানেজ করুন"</string> <string name="location_settings" msgid="8863940440881290182">"লোকেশন অ্যাক্সেস করা"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"অ্যাপ ও পরিষেবার জন্য। আপনি কোনও জরুরি নম্বরে কল করলে, এই সেটিং বন্ধ করা থাকলেও, মাইক্রোফোনের ডেটা শেয়ার করা হতে পারে"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"অ্যাপ ও পরিষেবার জন্য"</string> </resources> diff --git a/PermissionController/res/values-bn-watch/strings.xml b/PermissionController/res/values-bn-watch/strings.xml index f8c2968f8..698bdc32c 100644 --- a/PermissionController/res/values-bn-watch/strings.xml +++ b/PermissionController/res/values-bn-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"পাল্টানো যাবে না"</string> <string name="generic_yes" msgid="2489207724988649846">"হ্যাঁ"</string> <string name="generic_cancel" msgid="2631708607129269698">"বাতিল করুন"</string> + <string name="permission_access_always" msgid="2107115233573823032">"সব সময়ের জন্য"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"অ্যাপ ব্যবহার করার সময়"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"সব সময়ের জন্য"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"অ্যাপ ব্যবহার করার সময়"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"সব সময়ের জন্য"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"অ্যাপ ব্যবহার করার সময়"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"সব সময়ের জন্য"</string> </resources> diff --git a/PermissionController/res/values-bn/strings.xml b/PermissionController/res/values-bn/strings.xml index c17a53046..3670b2d11 100644 --- a/PermissionController/res/values-bn/strings.xml +++ b/PermissionController/res/values-bn/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"সব অনুমতি"</string> <string name="other_permissions" msgid="2901186127193849594">"অ্যাপের অন্যান্য কার্যক্ষমতা"</string> <string name="permission_request_title" msgid="8790310151025020126">"অনুমতির অনুরোধ"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear-এ ইনস্টল/আনইনস্টল করা যাবে না।"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অ্যাপটিকে কিসে কিসে অ্যাক্সেস দেবেন তা বেছে নিন"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> আপডেট করা হয়েছে৷ অ্যাপটিকে কিসে কিসে অ্যাক্সেস দেবেন তা বেছে নিন।"</string> <string name="review_button_cancel" msgid="2191147944056548886">"বাতিল করুন"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"সুনির্দিষ্ট লোকেশনের সুবিধা বন্ধ থাকলে, অ্যাপ আপনার আনুমানিক লোকেশন অ্যাক্সেস করতে পারবে"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> অনুমতি"</string> <string name="app_permission_header" msgid="2951363137032603806">"এই অ্যাপের জন্য <xliff:g id="PERM">%1$s</xliff:g> অ্যাক্সেস"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>-এ এই অ্যাপের জন্য <xliff:g id="PERM">%1$s</xliff:g>-এর অ্যাক্সেস"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g>-এর ক্ষেত্রে দেওয়া সব অনুমতি দেখুন"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"যেসব অ্যাপের এই অনুমতি আছে সেগুলি দেখুন"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistant-এর মাইক্রোফোন ব্যবহার সম্পর্কিত ডেটা দেখুন"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"অ্যাপ ব্যবহার করা না হলে সেটি থেকে অনুমতি প্রত্যাহার করে নিন"</string> <string name="unused_apps_label" msgid="2595428768404901064">"অনুমতি সরান এবং স্পেস খালি করুন"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"ব্যবহার না হলে অ্যাপ অ্যাক্টিভিটি পজ করুন"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ব্যবহার না করা হলে অ্যাপ ম্যানেজ করুন"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"অনুমতি সরান, অস্থায়ী ফাইল মুছুন এবং বিজ্ঞপ্তি বন্ধ করুন"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"অনুমতি সরান, অস্থায়ী ফাইল মুছুন, বিজ্ঞপ্তি বন্ধ করুন এবং অ্যাপ আর্কাইভ করুন"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"আপনার ডেটা সুরক্ষিত রাখতে এই অ্যাপ কয়েক মাস ব্যবহার করা না হলে, এটিকে দেওয়া অনুমতি প্রত্যাহার করে নেওয়া হবে।"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"আপনার ডেটা সুরক্ষিত রাখতে অ্যাপটি কয়েক মাস ব্যবহার করা না হলে, এই অনুমতি প্রত্যাহার করে নেওয়া হবে: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"আপনার ডেটা সুরক্ষিত রাখতে যেসব অ্যাপ গত কয়েক মাস ব্যবহার করা হয়নি সেগুলি থেকে অনুমতি প্রত্যাহার করে নেওয়া হয়েছে।"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"সমস্ত ফাইল ম্যানেজ করার অনুমতি দেওয়া হয়েছে"</string> <string name="ask_header" msgid="2633816846459944376">"প্রতিবার জিজ্ঞাসা করে"</string> <string name="denied_header" msgid="903209608358177654">"অনুমোদিত নয়"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>-এ <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"সব ফাইল অ্যাক্সেস করতে পারবে এমন আরও অ্যাপ দেখুন"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{১ দিন}one{# দিন}other{# দিন}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ঘণ্টা}one{# ঘণ্টা}other{# ঘণ্টা}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"নোট অ্যাপ"</string> <string name="role_notes_description" msgid="8496852798616883551">"অ্যাপ, যা আপনার ডিভাইসে নোট নেওয়ার অনুমতি দেয়"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"নোট"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ডিফল্ট ওয়ালেট অ্যাপ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"ওয়ালেট অ্যাপ"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"বিভিন্ন ধরনের ট্রানজ্যাকশনের ক্ষেত্রে আপনাকে সাহায্য করতে, ওয়ালেট অ্যাপ আপনার ক্রেডিট ও লয়ালটি কার্ড, গাড়ির \'কী\' এবং অন্যান্য জিনিস সেভ করতে পারবে।"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপকে আপনার ডিফল্ট ওয়ালেট অ্যাপ হিসেবে সেট করবেন?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"কোনও অনুমতির প্রয়োজন নেই"</string> <string name="request_role_current_default" msgid="738722892438247184">"বর্তমান ডিফল্ট"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"আর দেখতে চাই না"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ডিফল্ট হিসেবে রাখুন"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ডেটা শেয়ারিং সংক্রান্ত আপডেট"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"কিছু অ্যাপ আপনার লোকেশন ডেটা শেয়ার করার উপায়ের ক্ষেত্রে পরিবর্তন করেছে"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"সেটিংস"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>-এ অ্যাক্সেস করা হয়েছে"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"গতকাল <xliff:g id="TIME_DATE">%1$s</xliff:g>-এ অ্যাক্সেস করা হয়েছে"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g><xliff:g id="TIME_DATE_1">%2$s</xliff:g>-এ অ্যাক্সেস করা হয়েছে"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"আপনার একবার ব্যবহারের পাসওয়ার্ড হল ১২৩৪৩৫"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"বিধিনিষেধযুক্ত সেটিংস"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"আপনার নিরাপত্তার জন্য, এই সেটিং বর্তমানে উপলভ্য নেই।"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"অ্যাপকে <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> অ্যাক্সেস করতে দেওয়া হয়নি"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"অ্যাপটি সংবেদনশীল অনুমতি অ্যাক্সেস করার অনুরোধ জানিয়েছে, যার জন্য আপনার ব্যক্তিগত ও আর্থিক অবস্থা সম্পর্কিত তথ্যের ক্ষেত্রে ঝুঁকির সম্ভাবনা থাকতে পারে।<xliff:g id="ID_1"><br><br></xliff:g>এই সীমাবদ্ধ অনুমতি ছাড়া অ্যাপটি সঠিকভাবে কাজ না করার সম্ভাবনাও আছে। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>কীভাবে অ্যাক্সেস করার অনুমতি দেবেন সেই সম্পর্কে জানুন</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"অ্যাপকে ডিফল্ট <xliff:g id="ROLE_NAME">%1$s</xliff:g> হিসেবে কাজ করার অ্যাক্সেস দেওয়া হয়নি"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"অ্যাপটি সংবেদনশীল অনুমতি অ্যাক্সেস করার অনুরোধ জানিয়েছে, যার জন্য আপনার ব্যক্তিগত ও আর্থিক অবস্থা সম্পর্কিত তথ্যের ক্ষেত্রে ঝুঁকির সম্ভাবনা থাকতে পারে।<xliff:g id="ID_1"><br><br></xliff:g>এইসব সীমাবদ্ধ অনুমতি ছাড়া অ্যাপটি সঠিকভাবে কাজ না করার সম্ভাবনাও আছে। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>কীভাবে অ্যাক্সেস করার অনুমতি দেবেন সেই সম্পর্কে জানুন</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"অ্যাপকে অ্যাক্সেস দেওয়া হয়নি"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"এই অনুমতি অ্যাক্সেস করলে আপনার ব্যক্তিগত ও আর্থিক অবস্থা সম্পর্কিত তথ্যের ক্ষেত্রে ঝুঁকি তৈরি হতে পারে।<xliff:g id="ID_1"><br><br></xliff:g>এই অনুমতি ছাড়া এই অ্যাপ সঠিকভাবে কাজ না করার সম্ভাবনা থাকতে পারে। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>কীভাবে অ্যাক্সেস করার অনুমতি দেবেন সেই সম্পর্কে জানুন</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"আরও জানুন"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ঠিক আছে"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"অনুমতির অনুরোধ ব্লক করা হয়েছে"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"এই অ্যাপ অতিরিক্ত অনুমতির জন্য অনুরোধ করছে, কিন্তু স্ট্রিমিং সেশন চলাকালীন অনুমতি দেওয়া যাবে না। প্রথমে আপনার ফোনে অনুমতি দিন।"</string> </resources> diff --git a/PermissionController/res/values-bs-v34/strings.xml b/PermissionController/res/values-bs-v34/strings.xml index e2b8445df..d3e33f8e9 100644 --- a/PermissionController/res/values-bs-v34/strings.xml +++ b/PermissionController/res/values-bs-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Upravljajte pristupom aplikacije zdravstvenim podacima"</string> <string name="location_settings" msgid="8863940440881290182">"Pristup lokaciji"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Za aplikacije i usluge. Ako je ova postavka isključena, podaci mikrofona se i dalje mogu dijeliti kada pozovete broj za hitne slučajeve"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Za aplikacije i usluge"</string> </resources> diff --git a/PermissionController/res/values-bs-watch/strings.xml b/PermissionController/res/values-bs-watch/strings.xml index 1a15ad0b3..68f066963 100644 --- a/PermissionController/res/values-bs-watch/strings.xml +++ b/PermissionController/res/values-bs-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Ne mijenja se"</string> <string name="generic_yes" msgid="2489207724988649846">"Da"</string> <string name="generic_cancel" msgid="2631708607129269698">"Otkaži"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Cijelo vrijeme"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Dok se aplikacija koristi"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Cijelo vrijeme"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Dok se aplikacija koristi"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Cijelo vrijeme"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Dok se aplikacija koristi"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Cijelo vrijeme"</string> </resources> diff --git a/PermissionController/res/values-bs/strings.xml b/PermissionController/res/values-bs/strings.xml index 061ed86a1..d761d6159 100644 --- a/PermissionController/res/values-bs/strings.xml +++ b/PermissionController/res/values-bs/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Sva odobrenja"</string> <string name="other_permissions" msgid="2901186127193849594">"Ostale mogućnosti aplikacije"</string> <string name="permission_request_title" msgid="8790310151025020126">"Zahtjev za odobrenje"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Instaliranje/deinstaliranje nije podržano na Wearu."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Izaberite čemu aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g>&Lt;/b> može pristupiti"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplikacija &Lt;b><xliff:g id="APP_NAME">%1$s</xliff:g>&Lt;/b> je ažurirana. Izaberite čemu ova aplikacija može pristupiti."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Otkaži"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kada je tačna lokacija isključena, aplikacije mogu pristupiti vašoj približnoj lokaciji"</string> <string name="app_permission_title" msgid="2090897901051370711">"Odobrenje za: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Pristup aplikacije za: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Pristup aplikaciji \"<xliff:g id="PERM">%1$s</xliff:g>\" za ovu aplikaciju na uređaju \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Prikaži sva odobrenja aplikacije <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Prikaži sve aplikacije s ovim odobrenjem"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Prikaži korištenje mikrofona asistenta"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Ukloni odobrenja ako se aplikacija ne koristi"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Ukloni odobrenja i oslobodi prostor"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pauziraj aktivnost apl. ako se ne koristi"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Upravljanje aplikacijom ako se ne koristi"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Uklonite odobrenja, izbrišite privremene fajlove i zaustavite obavještenja"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Uklonite odobrenja, izbrišite privremene fajlove, zaustavite obavještenja i arhivirajte aplikaciju"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Zbog zaštite vaših podataka, odobrenja za ovu aplikaciju će se ukloniti ako se ona ne bude koristila nekoliko mjeseci."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Radi zaštite vaših podataka, ako se aplikacija ne bude koristila nekoliko mjeseci, uklonit će se sljedeća odobrenja: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Zbog zaštite vaših podataka uklonjena su odobrenja iz aplikacija koje niste koristili nekoliko mjeseci."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Dozvoljeno upravljanje svim fajlovima"</string> <string name="ask_header" msgid="2633816846459944376">"Pitaj svaki put"</string> <string name="denied_header" msgid="903209608358177654">"Nije dozvoljeno"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> na uređaju \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Pogledajte više aplikacija koje imaju pristup svim fajlovima"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dan}one{# dan}few{# dana}other{# dana}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# h}one{# h}few{# h}other{# h}}"</string> @@ -376,7 +378,7 @@ <string name="role_emergency_request_description" msgid="131645948770262850">"Nije potrebno odobrenje"</string> <string name="role_emergency_search_keywords" msgid="1920007722599213358">"hitni slučaj"</string> <string name="role_home_label" msgid="3871847846649769412">"Zadana apl. na početnom ekranu"</string> - <string name="role_home_short_label" msgid="8544733747952272337">"Aplikacija na početnom ekranu"</string> + <string name="role_home_short_label" msgid="8544733747952272337">"Aplikacija za početni ekran"</string> <string name="role_home_description" msgid="7997371519626556675">"Aplikacije, poznate i kao pokretači, koje zamjenjuju početne ekrane na Android uređaju te vam daju pristup sadržaju i funkcijama uređaja"</string> <string name="role_home_request_title" msgid="738136983453341081">"Postaviti aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> kao zadanu aplikaciju na početnom ekranu?"</string> <string name="role_home_request_description" msgid="2658833966716057673">"Nije potrebno odobrenje"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikacija za bilješke"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikacije koje vam dozvoljavaju da pravite bilješke na uređaju"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"bilješke"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Zadana aplikacija za novčanik"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikacija za novčanik"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplikacije za novčanik mogu pohranjivati kreditne kartice, kartice lojalnosti, ključeve automobila i druge stvari da vam pomognu pri raznim vrstama transakcija."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Postaviti aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> kao zadanu aplikaciju za novčanik?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nije potrebno odobrenje"</string> <string name="request_role_current_default" msgid="738722892438247184">"Trenutno zadano"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ne pitaj ponovo"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Postavi kao zadano"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Promjene u dijeljenju podataka"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Neke aplikacije mogu promijeniti način na koji mogu dijeliti podatke o lokaciji"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Postavke"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Pristupljeno je u <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Pristupljeno je jučer u <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Pristupljeno je <xliff:g id="TIME_DATE_0">%1$s</xliff:g> u <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Jednokratna lozinka je 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ograničena postavka"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Radi vaše sigurnosti postavka trenutno nije dostupna."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikaciji je odbijen pristup dopuštenju <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikacija je zatražila pristup dopuštenju za osjetljive podatke koje može ugroziti vaše osobne i financijske podatke.<xliff:g id="ID_1"><br><br></xliff:g>Moguće je da aplikacija neće pravilno funkcionirati bez tog ograničenog dopuštenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako omogućiti pristup</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikaciji je odbijen pristup da prema zadanim postavkama bude <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikacija je zatražila pristup dopuštenjima za osjetljive podatke koja mogu ugroziti vaše osobne i financijske podatke.<xliff:g id="ID_1"><br><br></xliff:g>Moguće je da aplikacija neće pravilno funkcionirati bez tih ograničenih dopuštenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako omogućiti pristup</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikaciji je odbijen pristup"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Pristup tom dopuštenju može ugroziti vaše osobne i financijske podatke.<xliff:g id="ID_1"><br><br></xliff:g>Moguće je da aplikacija neće pravilno funkcionirati bez tog ograničenog dopuštenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako omogućiti pristup</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Saznajte više"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Uredu"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Zahtjev za odobrenje je potisnut"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prijenosa. Najprije dajte odobrenje na telefonu."</string> </resources> diff --git a/PermissionController/res/values-ca-v34/strings.xml b/PermissionController/res/values-ca-v34/strings.xml index 8aad7b657..727208ace 100644 --- a/PermissionController/res/values-ca-v34/strings.xml +++ b/PermissionController/res/values-ca-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gestiona l\'accés de les aplicacions a les dades de salut"</string> <string name="location_settings" msgid="8863940440881290182">"Accés a la ubicació"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Per a aplicacions i serveis. És possible que les dades del micròfon es comparteixin si truques a un número d\'emergència encara que aquesta opció estigui desactivada."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Per a aplicacions i serveis"</string> </resources> diff --git a/PermissionController/res/values-ca-watch/strings.xml b/PermissionController/res/values-ca-watch/strings.xml index a7ba423ff..41bdada45 100644 --- a/PermissionController/res/values-ca-watch/strings.xml +++ b/PermissionController/res/values-ca-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"No es pot canviar"</string> <string name="generic_yes" msgid="2489207724988649846">"Sí"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancel·la"</string> + <string name="permission_access_always" msgid="2107115233573823032">"En tot moment"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Quan s\'utilitza l\'aplicació"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"En tot moment"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Quan s\'utilitza l\'aplicació"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"En tot moment"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Quan s\'utilitza l\'aplicació"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"En tot moment"</string> </resources> diff --git a/PermissionController/res/values-ca/strings.xml b/PermissionController/res/values-ca/strings.xml index 729b8f20f..3b6ee45bd 100644 --- a/PermissionController/res/values-ca/strings.xml +++ b/PermissionController/res/values-ca/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Tots els permisos"</string> <string name="other_permissions" msgid="2901186127193849594">"Altres competències de l\'aplicació"</string> <string name="permission_request_title" msgid="8790310151025020126">"Sol·licitud de permís"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Les accions d\'instal·lar o de desinstal·lar no s\'admeten a Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Tria a què vols que tingui accés <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"S\'ha actualitzat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Tria a què vols que tingui accés aquesta aplicació."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancel·la"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Quan la ubicació precisa està desactivada, les aplicacions poden accedir a la teva ubicació aproximada"</string> <string name="app_permission_title" msgid="2090897901051370711">"Permís d\'accés a <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Accés a <xliff:g id="PERM">%1$s</xliff:g> per a aquesta aplicació"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Accés de <xliff:g id="PERM">%1$s</xliff:g> a aquesta aplicació (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Mostra tots els permisos per a <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Mostra totes les aplicacions que tenen aquest permís"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostra l\'ús del micròfon de l\'Assistent"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Suprimeix els permisos si no s\'utilitza l\'aplicació"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Suprimeix els permisos i allibera espai"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Activitat a l\'app en pausa si no s\'usa"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gestiona l\'aplicació si no s\'utilitza"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Suprimeix els permisos i els fitxers temporals, i atura les notificacions"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Suprimeix els permisos, elimina els fitxers temporals, atura les notificacions i arxiva l\'aplicació"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Per protegir les teves dades, els permisos d\'aquesta aplicació se suprimiran si no la utilitzes durant uns mesos."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Si l\'aplicació no s\'utilitza durant uns mesos, se suprimiran els permisos següents per protegir les teves dades: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Per protegir les teves dades, s\'han suprimit els permisos de les aplicacions que no has utilitzat durant els darrers mesos."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Poden gestionar tots els fitxers"</string> <string name="ask_header" msgid="2633816846459944376">"Pregunta sempre"</string> <string name="denied_header" msgid="903209608358177654">"Sense permís"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Mostra més aplicacions que poden accedir a tots els fitxers"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dia}many{# dies}other{# dies}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hora}many{# hores}other{# hores}}"</string> @@ -292,7 +294,7 @@ <string name="notification_listener_remove_access_success_label" msgid="2477611529875633107">"S\'ha suprimit l\'accés"</string> <string name="accessibility_access_reminder_notification_title" msgid="2971317234668807566">"Revisa l\'aplicació amb accés complet al dispositiu"</string> <string name="accessibility_access_reminder_notification_content" msgid="7389454158175306720">"<xliff:g id="APP_NAME">%s</xliff:g> pot veure la pantalla i dur a terme accions al dispositiu. Les aplicacions d\'accessibilitat necessiten aquest tipus d\'accés perquè funcionin de la manera prevista."</string> - <string name="accessibility_access_warning_card_content" msgid="4370327190293217358">"Aquesta aplicació pot veure la pantalla i dur a terme accions al dispositiu. Les aplicacions d\'accessibilitat necessiten aquest tipus d\'accés perquè funcionin de la manera prevista, però comprova l\'aplicació i assegura\'t que sigui de confiança."</string> + <string name="accessibility_access_warning_card_content" msgid="4370327190293217358">"Aquesta aplicació pot veure la pantalla i dur a terme accions al dispositiu. Les aplicacions d\'accessibilitat necessiten aquest tipus d\'accés perquè funcionin de la manera prevista, però comprova l\'aplicació i assegura\'t que hi confies."</string> <string name="accessibility_remove_access_button_label" msgid="44145801526711640">"Suprimeix l\'accés"</string> <string name="accessibility_show_all_apps_button_label" msgid="960067249326392280">"Veure les aplicacions amb accés complet"</string> <string name="accessibility_remove_access_success_label" msgid="4380995302917014670">"S\'ha suprimit l\'accés"</string> @@ -399,10 +401,15 @@ <string name="role_watch_description" msgid="267003778693177779">"<xliff:g id="APP_NAME">%1$s</xliff:g> tindrà permís per interaccionar amb les teves notificacions i accedir al telèfon, SMS, contactes i calendari."</string> <string name="role_app_streaming_description" msgid="7341638576226183992">"<xliff:g id="APP_NAME">%1$s</xliff:g> tindrà permís per interaccionar amb les teves notificacions i reproduir en continu les teves aplicacions al dispositiu connectat."</string> <string name="role_companion_device_computer_description" msgid="416099879217066377">"Aquest servei comparteix les fotos, el contingut multimèdia i les notificacions del telèfon amb altres dispositius."</string> - <string name="role_notes_label" msgid="7451627001058089536">"App de notes predeterminada"</string> + <string name="role_notes_label" msgid="7451627001058089536">"Aplicació de notes predeterminada"</string> <string name="role_notes_short_label" msgid="8796604147546125285">"Aplicació de notes"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplicacions que et permeten prendre notes al dispositiu"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"App de cartera predeterminada"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplicació de cartera"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Les aplicacions de cartera poden emmagatzemar les targetes de crèdit i de fidelització, les claus del cotxe i altres elements per ajudar-te amb diverses formes de transaccions."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Vols definir <xliff:g id="APP_NAME">%1$s</xliff:g> com l\'aplicació de cartera predeterminada?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No calen permisos"</string> <string name="request_role_current_default" msgid="738722892438247184">"Predeterminada actualment"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"No m\'ho tornis a preguntar"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Estableix com a predeterminada"</string> @@ -460,7 +467,7 @@ <string name="permgrouprequest_device_aware_storage_isolated" msgid="5934218468708513375">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a les fotos i al contingut multimèdia del dispositiu <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi als contactes?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi als contactes del dispositiu <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_location" msgid="6990232580121067883">"Permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu?"</string> + <string name="permgrouprequest_location" msgid="6990232580121067883">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu?"</string> <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"L\'aplicació només tindrà accés a la ubicació quan l\'estiguis utilitzant"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Canvis en la compartició de dades"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Algunes aplicacions han canviat la manera en què poden compartir les teves dades d\'ubicació"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Configuració"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"S\'hi ha accedit a les <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"S\'hi va accedir ahir a les <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"S\'hi ha accedit el dia <xliff:g id="TIME_DATE_0">%1$s</xliff:g> a les <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"La contrasenya d\'un sol ús és 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Opció de configuració restringida"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Per a la teva seguretat, aquesta opció de configuració no està disponible en aquests moments."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"A l\'aplicació se li ha denegat l\'accés a <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"L\'aplicació ha demanat accés a un permís sensible, el qual pot posar en risc la teva informació personal o financera.<xliff:g id="ID_1"><br><br></xliff:g>És possible que l\'aplicació no funcioni correctament sense aquest permís restringit. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Més informació sobre com pots permetre l\'accés</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"A l\'aplicació se li ha denegat l\'accés per ser l’<xliff:g id="ROLE_NAME">%1$s</xliff:g> predeterminada"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"L\'aplicació ha demanat accés a permisos sensibles, els quals poden posar en risc la teva informació personal o financera.<xliff:g id="ID_1"><br><br></xliff:g>És possible que l\'aplicació no funcioni correctament sense aquests permisos restringits. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Més informació sobre com pots permetre l\'accés</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"A l\'aplicació se li ha denegat l\'accés"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"L\'accés a aquest permís pot posar en risc la teva informació personal i financera.<xliff:g id="ID_1"><br><br></xliff:g>És possible que l\'aplicació no funcioni correctament sense aquest permís. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Més informació sobre com pots permetre l\'accés</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Més informació"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"D\'acord"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"S\'ha suprimit la sol·licitud de permís"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Aquesta aplicació requereix permisos addicionals, però els permisos no es poden concedir en una sessió d\'estríming. Primer concedeix el permís al teu telèfon."</string> </resources> diff --git a/PermissionController/res/values-cs-v34/strings.xml b/PermissionController/res/values-cs-v34/strings.xml index b7e982b21..dd60a422d 100644 --- a/PermissionController/res/values-cs-v34/strings.xml +++ b/PermissionController/res/values-cs-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Správa přístupu aplikací ke zdravotním údajům"</string> <string name="location_settings" msgid="8863940440881290182">"Přístup k poloze"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Aplikace a služby. Pokud je toto nastavení vypnuté a zavoláte na číslo tísňového volání, data z mikrofonu bude možné nadále sdílet"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Aplikace a služby"</string> </resources> diff --git a/PermissionController/res/values-cs-watch/strings.xml b/PermissionController/res/values-cs-watch/strings.xml index eca4682c4..5e1a4b022 100644 --- a/PermissionController/res/values-cs-watch/strings.xml +++ b/PermissionController/res/values-cs-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Nelze změnit"</string> <string name="generic_yes" msgid="2489207724988649846">"Ano"</string> <string name="generic_cancel" msgid="2631708607129269698">"Zrušit"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Neustále"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Při používání aplikace"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Neustále"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Při používání aplikace"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Neustále"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Při používání aplikace"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Neustále"</string> </resources> diff --git a/PermissionController/res/values-cs/strings.xml b/PermissionController/res/values-cs/strings.xml index 20c594403..ddb568b2b 100644 --- a/PermissionController/res/values-cs/strings.xml +++ b/PermissionController/res/values-cs/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Všechna oprávnění"</string> <string name="other_permissions" msgid="2901186127193849594">"Ostatní oprávnění aplikace"</string> <string name="permission_request_title" msgid="8790310151025020126">"Žádost o oprávnění"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Akce instalace/odinstalace nejsou v zařízení Wear podporovány."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Určete, k čemu aplikaci <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> povolíte přístup"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> byla aktualizována. Určete, k čemu jí povolíte přístup."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Zrušit"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Když je přesná poloha vypnutá, aplikace mají přístup k vaší přibližné poloze"</string> <string name="app_permission_title" msgid="2090897901051370711">"Oprávnění: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Přístup této aplikace k oprávnění: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Přístup k <xliff:g id="PERM">%1$s</xliff:g> pro tuto aplikaci v zařízení <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Zobrazit všechna oprávnění aplikace <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Zobrazit všechny aplikace s tímto oprávněním"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Zobrazit používání mikrofonu asistentem"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Odebrat oprávnění, pokud se aplikace nepoužívá"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Odebrat oprávnění a uvolnit místo"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pozastavit aktivitu při nepoužívání"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Spravovat aplikaci, pokud se nepoužívá"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Odebrat oprávnění, smazat dočasné soubory a zastavit oznámení"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Odebrat oprávnění, smazat dočasné soubory, zastavit oznámení a archivovat aplikaci"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Pokud tuto aplikaci několik měsíců nepoužijete, kvůli ochraně vašich dat jí budou oprávnění odebrána."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Pokud tuto aplikaci několik měsíců nepoužijete, budou jí kvůli ochraně vašich dat odebrána následující oprávnění: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Za účelem ochrany vašich dat byla odebrána oprávnění aplikacím, které jste několik měsíců nepoužili."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Povolena správa všech souborů"</string> <string name="ask_header" msgid="2633816846459944376">"Pokaždé se zeptat"</string> <string name="denied_header" msgid="903209608358177654">"Nepovoleno"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> na <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Zobrazit další aplikace s přístupem ke všem souborům"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 den}few{# dny}many{# dne}other{# dní}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hodinu}few{# hodiny}many{# hodiny}other{# hodin}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikace pro poznámky"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikace, které umožňují dělat si na zařízení poznámky."</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"poznámky"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Výchozí aplikace typu peněženka"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikace typu peněženka"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplikace typu peněženka můžou uložit vaše platební a věrnostní karty, klíče od auta a další věci, a usnadnit vám různé transakce."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Nastavit aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> jako výchozí peněženku?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nejsou potřeba žádná oprávnění"</string> <string name="request_role_current_default" msgid="738722892438247184">"Aktuálně výchozí"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Příště se neptat"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Změnit na výchozí"</string> @@ -610,7 +617,7 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"Přístup k mikrofonu"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Aplikace a služby"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Týká se aplikací a služeb. Pokud je toto nastavení vypnuté a zavoláte na číslo tísňového volání, data z mikrofonu se mohou stále sdílet."</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"Podívejte se, které aplikace a služby mají přístup k poloze"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"Seznam aplikací a služeb, které mají přístup k poloze"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Zobrazovat použití schránky"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Zobrazovat zprávu, když aplikace použijí text, obrázky nebo jiný obsah, který jste zkopírovali"</string> <string name="show_password_title" msgid="2877269286984684659">"Zobrazovat hesla"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Aktualizace sdílení dat"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Některé aplikace změnily způsob, kterým mohou sdílet údaje o vaší poloze"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Nastavení"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Poslední přístup: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Poslední přístup: včera v <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Poslední přístup: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Vaše jednorázové heslo je 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Blokované nastavení"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Z důvodu vaší bezpečnosti toto nastavení momentálně není dostupné."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikaci byl odepřen přístup k oprávnění <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikace požádala o přístup k citlivému oprávnění, které může ohrozit vaše osobní a finanční údaje.<xliff:g id="ID_1"><br><br></xliff:g>Je možné, že aplikace bez tohoto oprávnění nebude fungovat správně. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Jak povolit přístup</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikaci byla odepřena role výchozí <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikace požádala o přístup k citlivým oprávněním, která mohou ohrozit vaše osobní a finanční údaje.<xliff:g id="ID_1"><br><br></xliff:g>Je možné, že aplikace nebude bez těchto omezených oprávnění fungovat správně. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Jak povolit přístup</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikaci byl odepřen přístup"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Přístup k tomuto oprávnění může ohrozit vaše osobní a finanční údaje.<xliff:g id="ID_1"><br><br></xliff:g>Je možné, že aplikace bez tohoto oprávnění nebude fungovat správně. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Jak povolit přístup</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Další informace"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Žádost o oprávnění byla potlačena"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Tato aplikace požaduje další oprávnění, která ale nelze udělit během relace streamování. Oprávnění udělte nejprve na telefonu."</string> </resources> diff --git a/PermissionController/res/values-da-v34/strings.xml b/PermissionController/res/values-da-v34/strings.xml index 5777a6832..38dc3c7b8 100644 --- a/PermissionController/res/values-da-v34/strings.xml +++ b/PermissionController/res/values-da-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Administrer appadgang til sundhedsdata"</string> <string name="location_settings" msgid="8863940440881290182">"Lokationsadgang"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"For apps og tjenester. Hvis denne indstilling er deaktiveret, deles mikrofondata muligvis stadig, når du ringer til et alarmnummer"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"For apps og tjenester"</string> </resources> diff --git a/PermissionController/res/values-da-watch/strings.xml b/PermissionController/res/values-da-watch/strings.xml index 022b2f562..d78c45ff4 100644 --- a/PermissionController/res/values-da-watch/strings.xml +++ b/PermissionController/res/values-da-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Kan ikke ændres"</string> <string name="generic_yes" msgid="2489207724988649846">"Ja"</string> <string name="generic_cancel" msgid="2631708607129269698">"Annuller"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Hele tiden"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Når appen er i brug"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Hele tiden"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Når appen er i brug"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Hele tiden"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Når appen er i brug"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Hele tiden"</string> </resources> diff --git a/PermissionController/res/values-da/strings.xml b/PermissionController/res/values-da/strings.xml index 7655150ee..16c09e743 100644 --- a/PermissionController/res/values-da/strings.xml +++ b/PermissionController/res/values-da/strings.xml @@ -31,7 +31,7 @@ <string name="grant_dialog_button_deny_and_dont_ask_again" msgid="1748925431574312595">"Tillad ikke, og spørg ikke igen"</string> <string name="grant_dialog_button_no_upgrade" msgid="8344732743633736625">"Behold \"Mens appen er i brug\""</string> <string name="grant_dialog_button_no_upgrade_one_time" msgid="5125892775684968694">"Behold \"Kun denne ene gang\""</string> - <string name="grant_dialog_button_more_info" msgid="213350268561945193">"Mere info"</string> + <string name="grant_dialog_button_more_info" msgid="213350268561945193">"Flere oplysninger"</string> <string name="grant_dialog_button_allow_all" msgid="5939066403732409516">"Tillad alle"</string> <string name="grant_dialog_button_always_allow_all" msgid="1719900027660252167">"Tillad altid alle"</string> <string name="grant_dialog_button_allow_limited_access" msgid="5713551784422137594">"Tillad begrænset adgang"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Alle tilladelser"</string> <string name="other_permissions" msgid="2901186127193849594">"Andre app-egenskaber"</string> <string name="permission_request_title" msgid="8790310151025020126">"Anmodning om tilladelse"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Det er ikke muligt at installere/afinstallere på Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Vælg, hvad <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> må få adgang til"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> er blevet opdateret. Vælg, hvad denne app må få adgang til."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Annuller"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Når den præcise lokation er slået fra, kan apps få adgang til din omtrentlige lokation"</string> <string name="app_permission_title" msgid="2090897901051370711">"Tilladelse til <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Adgang til <xliff:g id="PERM">%1$s</xliff:g> for denne app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"adgang til <xliff:g id="PERM">%1$s</xliff:g> for denne app på <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Se alle tilladelser for <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Se alle apps med denne tilladelse"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Vis brug af Assistent-mikrofonen"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Fjern tilladelser, hvis appen ikke bruges"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Fjern tilladelser, og frigør plads"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Sæt appaktivitet på pause ved inaktivitet"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Administrer appen, hvis den ikke bruges"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Fjern tilladelser, slet midlertidige filer, og stop notifikationer"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Fjern tilladelser, slet midlertidige filer, deaktiver notifikationer, og arkivér appen"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Hvis appen ikke bliver brugt i et par måneder, fjernes tilladelser for appen for at beskytte dine data."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Hvis appen ikke bliver brugt i et par måneder, fjernes følgende tilladelser for at beskytte dine data: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Tilladelserne til apps, du ikke har brugt i et par måneder, er blevet fjernet for at beskytte dine data."</string> @@ -238,7 +239,7 @@ <string name="permission_description_summary_nearby_devices" msgid="8269183818275073741">"Apps med denne tilladelse kan finde, oprette forbindelse til og fastslå den relative placering af enheder i nærheden"</string> <string name="permission_description_summary_microphone" msgid="630834800308329907">"Apps med denne tilladelse kan optage lyd"</string> <string name="permission_description_summary_phone" msgid="4515277217435233619">"Apps med denne tilladelse kan foretage og administrere telefonopkald"</string> - <string name="permission_description_summary_sensors" msgid="1836045815643119949">"Apps med denne tilladelse kan få adgang til sensordata om dine livstegn"</string> + <string name="permission_description_summary_sensors" msgid="1836045815643119949">"Apps med denne tilladelse kan få adgang til sensordata om dine vitale værdier"</string> <string name="permission_description_summary_sms" msgid="725999468547768517">"Apps med denne tilladelse kan sende og se sms-beskeder"</string> <string name="permission_description_summary_storage" msgid="6575759089065303346">"Apps med denne tilladelse har adgang til billeder, medier og filer på din enhed"</string> <string name="permission_description_summary_read_media_aural" msgid="3354728149930482199">"Apps med denne tilladelse kan tilgå musik og andre lydfiler på denne enhed"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Har tilladelse til at administrere alle filer"</string> <string name="ask_header" msgid="2633816846459944376">"Spørg hver gang"</string> <string name="denied_header" msgid="903209608358177654">"Ikke tilladt"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> på <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Se flere apps, som kan tilgå alle filer"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dag}one{# dag}other{# dage}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# time}one{# time}other{# timer}}"</string> @@ -352,10 +354,10 @@ <string name="role_assistant_label" msgid="4727586018198208128">"Standardapp for digital assistent"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"App for digital assistent"</string> <string name="role_assistant_description" msgid="6622458130459922952">"Assistanceapps kan hjælpe dig på baggrund af oplysningerne på den aktuelle skærm. Nogle apps understøtter både startertjenester og tjenester til indtaling for at give dig integreret assistance."</string> - <string name="role_browser_label" msgid="2877796144554070207">"Standardbrowserapp"</string> + <string name="role_browser_label" msgid="2877796144554070207">"Standardapp til browsing"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"Browserapp"</string> <string name="role_browser_description" msgid="3465253637499842671">"Apps, der giver dig adgang til internettet og viser links, som du trykker på"</string> - <string name="role_browser_request_title" msgid="2895200507835937192">"Vil du angive <xliff:g id="APP_NAME">%1$s</xliff:g> som din standardbrowserapp?"</string> + <string name="role_browser_request_title" msgid="2895200507835937192">"Vil du angive <xliff:g id="APP_NAME">%1$s</xliff:g> som din standardapp til browsing?"</string> <string name="role_browser_request_description" msgid="5888803407905985941">"Der kræves ingen tilladelser"</string> <string name="role_dialer_label" msgid="1100224146343237968">"Standardapp til opkald"</string> <string name="role_dialer_short_label" msgid="7186888549465352489">"Opkaldsapp"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"App til notetagning"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps, som giver dig mulighed for at tage noter på din enhed"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"noter"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Standardapp til digital pung"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"App til digital pung"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Apps til digitale punge kan gemme dine kredit- og loyalitetskort, bilnøgler m.m. for at hjælpe med forskellige former for transaktioner."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Vil du angive <xliff:g id="APP_NAME">%1$s</xliff:g> som din standardapp til digital pung?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Der kræves ingen tilladelser"</string> <string name="request_role_current_default" msgid="738722892438247184">"Nuværende standardapp"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Spørg ikke igen"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Angiv som standard"</string> @@ -622,8 +629,8 @@ <string name="permission_rationale_data_sharing_source_message" msgid="8330794595417986883">"Udvikleren gav oplysninger til "<annotation id="link"><annotation id="install_source" example="App Store">"%1$s"</annotation></annotation>" om, hvordan denne app deler data. Udvikleren opdaterer muligvis disse oplysninger senere."</string> <string name="permission_rationale_location_purpose_title" msgid="5115877143670012618">"Denne app deler muligvis lokationsdata for:"</string> <string name="permission_rationale_permission_data_sharing_varies_title" msgid="9103718980919908316">"Datadeling varierer"</string> - <string name="permission_rationale_data_sharing_varies_message" msgid="4224469559084489222">"Databehandlingen kan variere afhængigt af din appversion, din brug, dit område og din alder. "<annotation id="link">"Flere oplysninger om datadeling"</annotation></string> - <string name="permission_rationale_data_sharing_varies_message_without_link" msgid="4912763761399025094">"Databehandlingen kan variere afhængigt af din appversion, din brug, dit område og din alder."</string> + <string name="permission_rationale_data_sharing_varies_message" msgid="4224469559084489222">"Databehandlingen kan variere afhængigt af din appversion, din brug, din region og din alder. "<annotation id="link">"Flere oplysninger om datadeling"</annotation></string> + <string name="permission_rationale_data_sharing_varies_message_without_link" msgid="4912763761399025094">"Databehandlingen kan variere afhængigt af din appversion, din brug, din region og din alder."</string> <string name="permission_rationale_location_settings_title" msgid="7204145004850190953">"Dine lokationsdata"</string> <string name="permission_rationale_permission_settings_message" msgid="631286040979660267">"Skift denne apps adgang i "<annotation id="link">"privatlivsindstillingerne"</annotation></string> <string name="permission_rationale_purpose_app_functionality" msgid="8397736681065841405">"Appfunktionalitet"</string> @@ -639,7 +646,7 @@ <string name="data_sharing_updates_title" msgid="7996933386875213859">"Opdateringer om deling af lokationsdata"</string> <string name="data_sharing_updates_summary" msgid="764113985772233889">"Gennemse apps, der har ændret måden, hvorpå de kan dele dine lokationsdata"</string> <string name="data_sharing_updates_subtitle" msgid="6311537708950632329">"Disse apps har ændret den måde, hvorpå de kan dele dine lokationsdata. De har muligvis ikke delt dataene før eller kan nu anvende dem til annoncering eller marketing."</string> - <string name="data_sharing_updates_footer_message" msgid="1582711655172892107">"Udviklerne af disse apps har givet oplysninger om deres procedurer for datadeling til en appbutik. De kan opdatere procedurerne med tiden.\n\nProcedurer for datadeling kan variere afhængigt af din appversion, din brug, dit område og din alder."</string> + <string name="data_sharing_updates_footer_message" msgid="1582711655172892107">"Udviklerne af disse apps har givet oplysninger om deres procedurer for datadeling til en appbutik. De kan opdatere procedurerne med tiden.\n\nProcedurer for datadeling kan variere afhængigt af din appversion, din brug, din region og din alder."</string> <string name="learn_about_data_sharing" msgid="4200480587079488045">"Få flere oplysninger om deling af data"</string> <string name="shares_location_with_third_parties" msgid="2278051743742057767">"Dine lokationsdata deles nu med tredjeparter"</string> <string name="shares_location_with_third_parties_for_advertising" msgid="1918588064014480513">"Dine lokationsdata deles nu med tredjeparter med henblik på annoncering eller marketing"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Opdateringer om datadeling"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Nogle apps har ændret måden, hvorpå de kan dele dine lokationsdata"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Indstillinger"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Tilgået kl. <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Tilgået i går kl. <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Tilgået <xliff:g id="TIME_DATE_0">%1$s</xliff:g> kl. <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Din engangskode er 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Begrænset indstilling"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Af hensyn til din sikkerhed er denne indstilling i øjeblikket ikke tilgængelig."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Appen blev nægtet adgang til <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Appen anmodede om adgang til en følsom tilladelse, der kan kompromittere dine personlige eller økonomiske oplysninger.<xliff:g id="ID_1"><br><br></xliff:g>Appen fungerer muligvis ikke korrekt uden denne begrænsede tilladelse. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Se, hvordan du giver tilladelse</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Appen blev nægtet adgang til at være <xliff:g id="ROLE_NAME">%1$s</xliff:g> som standard"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Appen anmodede om adgang til en følsom tilladelse, der kan kompromittere dine personlige eller økonomiske oplysninger.<xliff:g id="ID_1"><br><br></xliff:g>Appen fungerer muligvis ikke korrekt uden denne begrænsede tilladelse. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Se, hvordan du giver tilladelse</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Appen blev nægtet adgang"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Hvis du giver adgang til denne tilladelse, kan dine personlige og økonomiske oplysninger kompromitteres.<xliff:g id="ID_1"><br><br></xliff:g>Appen fungerer muligvis ikke korrekt uden denne begrænsede tilladelse. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Se, hvordan du giver tilladelse</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Få flere oplysninger"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Anmodning om tilladelse blokeret"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Denne app anmoder om yderligere tilladelser, men der kan ikke gives tilladelser under en streamingsession. Giv tilladelse på din telefon først."</string> </resources> diff --git a/PermissionController/res/values-de-v34/strings.xml b/PermissionController/res/values-de-v34/strings.xml index ed699cce3..f85972421 100644 --- a/PermissionController/res/values-de-v34/strings.xml +++ b/PermissionController/res/values-de-v34/strings.xml @@ -22,6 +22,5 @@ <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> <string name="health_connect_summary" msgid="815473513776882296">"App-Zugriff auf Gesundheitsdaten verwalten"</string> <string name="location_settings" msgid="8863940440881290182">"Standortzugriff"</string> - <string name="mic_toggle_description" msgid="1504101620086616040">"Für Apps und Dienste. Wenn du eine Notrufnummer wählst, können Mikrofondaten trotz Deaktivierung dieser Berechtigung weitergegeben werden."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Für Apps und Dienste"</string> + <string name="mic_toggle_description" msgid="1504101620086616040">"Für Apps und Dienste. Wenn du eine Notrufnummer wählst, können Mikrofondaten weitergegeben werden, auch wenn diese Berechtigung deaktiviert ist."</string> </resources> diff --git a/PermissionController/res/values-de-watch/strings.xml b/PermissionController/res/values-de-watch/strings.xml index 617413a19..dbe09e316 100644 --- a/PermissionController/res/values-de-watch/strings.xml +++ b/PermissionController/res/values-de-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Änderung unmöglich"</string> <string name="generic_yes" msgid="2489207724988649846">"Ja"</string> <string name="generic_cancel" msgid="2631708607129269698">"Abbrechen"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Immer"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Beim Verwenden der App"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Immer"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Beim Verwenden der App"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Immer"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Beim Verwenden der App"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Immer"</string> </resources> diff --git a/PermissionController/res/values-de/strings.xml b/PermissionController/res/values-de/strings.xml index 4b862e97d..bde63ec81 100644 --- a/PermissionController/res/values-de/strings.xml +++ b/PermissionController/res/values-de/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Alle Berechtigungen"</string> <string name="other_permissions" msgid="2901186127193849594">"Andere App-Funktionen"</string> <string name="permission_request_title" msgid="8790310151025020126">"Berechtigungsanfrage"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Installations-/Deinstallationsaktion auf Android Wear nicht unterstützt."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Worauf darf die App <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> zugreifen?"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Die App <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wurde aktualisiert. Worauf darf diese App zugreifen?"</string> <string name="review_button_cancel" msgid="2191147944056548886">"Abbrechen"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Wenn der genaue Standort deaktiviert ist, können Apps auf deinen ungefähren Standort zugreifen"</string> <string name="app_permission_title" msgid="2090897901051370711">"Berechtigung: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Dieser App Zugriff auf <xliff:g id="PERM">%1$s</xliff:g> erlauben?"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g>-Zugriff für diese App auf dem <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Alle Berechtigungen der App „<xliff:g id="APP">%1$s</xliff:g>“ anzeigen"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Alle Apps mit dieser Berechtigung anzeigen"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Nutzung der Berechtigung \"Mikrofon\" für Assistant anzeigen"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Berechtigungen entfernen, wenn die App nicht verwendet wird"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Berechtigungen löschen und Speicherplatz freigeben"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"App-Aktivität bei Nichtnutzung stoppen"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"App-Verhalten bei Nichtnutzung verwalten"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Berechtigungen entfernen, temporäre Dateien löschen und Benachrichtigungen stoppen"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Berechtigungen entfernen, temporäre Dateien löschen, Benachrichtigungen stoppen und die App archivieren"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Zum Schutz deiner Daten werden dieser App die Berechtigungen entzogen, wenn du sie einige Monate nicht verwendest."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Zum Schutz deiner Daten werden dieser App die folgenden Berechtigungen entzogen, wenn du sie einige Monate nicht verwendest: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Zum Schutz deiner Daten wurden Apps, die du einige Monate nicht verwendet hast, Berechtigungen entzogen."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Verwalten aller Dateien zugelassen"</string> <string name="ask_header" msgid="2633816846459944376">"Jedes Mal fragen"</string> <string name="denied_header" msgid="903209608358177654">"Nicht zugelassen"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> auf dem <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Weitere Apps anzeigen, die auf alle Dateien zugreifen können"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 Tag}other{# Tage}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# Stunde}other{# Stunden}}"</string> @@ -351,7 +353,7 @@ <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"Diese Apps können deinen Bildschirm, deine Aktionen und deine Eingaben sehen, Aktionen ausführen und den Bildschirm steuern."</string> <string name="role_assistant_label" msgid="4727586018198208128">"Standard-App digit. Assistent"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"App für digitalen Assistenten"</string> - <string name="role_assistant_description" msgid="6622458130459922952">"Assistent-Apps können dir bei bestimmten Dingen helfen. Dazu greifen sie auf die Informationen zu, die aktuell auf deinem Bildschirm angezeigt werden. Damit sie dir eine umfassende Hilfe sind, unterstützen einige Apps sowohl Launcher- als auch Spracheingabedienste."</string> + <string name="role_assistant_description" msgid="6622458130459922952">"Assistent-Apps können dir bei bestimmten Dingen helfen. Dazu greifen sie auf die Informationen zu, die aktuell auf deinem Bildschirm angezeigt werden. Einige Apps unterstützen sowohl Launcher- als auch Spracheingabedienste."</string> <string name="role_browser_label" msgid="2877796144554070207">"Standard-Browser-App"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"Browser-App"</string> <string name="role_browser_description" msgid="3465253637499842671">"Apps, mit denen du auf das Internet zugreifen kannst und die die entsprechende Seite öffnen, wenn du auf einen Link tippst"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notizen-App"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps zum Erstellen von Notizen auf deinem Gerät"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"Notizen"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Standard-Wallet-App"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet-App"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"In Wallet-Apps kannst du deine Kredit- und Kundenkarten, Autoschlüssel und andere Dinge speichern, was dir bei verschiedenen Arten von Transaktionen hilft."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> als Standard-Wallet-App festlegen?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Keine Berechtigungen erforderlich"</string> <string name="request_role_current_default" msgid="738722892438247184">"Aktueller Standard"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Nicht mehr fragen"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Als Standard festlegen"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ erlauben, auf deine Kontakte zuzugreifen?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Darf <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> auf deinem <b><xliff:g id="DEVICE">%2$s</xliff:g></b> auf die Kontakte zugreifen?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> erlauben, den Gerätestandort abzurufen?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Darf <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> auf deinem <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>s</b> auf die Standortdaten zugreifen?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Darf <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> auf deinem <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> auf die Standortdaten zugreifen?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Die App hat nur Zugriff auf den Gerätestandort, solange du sie verwendest"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> erlauben, den Gerätestandort abzurufen?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Darf <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> auf deinem <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g><b> auf die Standortdaten zugreifen?"</string> @@ -609,7 +616,7 @@ <string name="camera_toggle_title" msgid="1251201397431837666">"Kamerazugriff"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"Mikrofonzugriff"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Für Apps und Dienste"</string> - <string name="mic_toggle_description" msgid="9163104307990677157">"Für Apps und Dienste. Wenn diese Einstellung deaktiviert ist, können Mikrofondaten dennoch freigegeben werden, wenn du den Notruf wählst."</string> + <string name="mic_toggle_description" msgid="9163104307990677157">"Für Apps und Dienste. Wenn du eine Notrufnummer wählst, können Mikrofondaten weitergegeben werden, auch wenn diese Berechtigung deaktiviert ist."</string> <string name="location_settings_subtitle" msgid="2328360561197430695">"Apps und Dienste sehen, die Zugriff auf diesen Standort haben"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Zugriff auf Zwischenablage anzeigen"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Eine Meldung wird angezeigt, wenn Apps auf Text, Bilder oder andere Inhalte zugreifen, die du kopiert hast"</string> @@ -625,7 +632,7 @@ <string name="permission_rationale_data_sharing_varies_message" msgid="4224469559084489222">"Die Art der Datennutzung kann von der Version und Verwendung der App, von der Region und vom Alter des Nutzers abhängen. "<annotation id="link">"Weitere Informationen zur Datenweitergabe"</annotation></string> <string name="permission_rationale_data_sharing_varies_message_without_link" msgid="4912763761399025094">"Die Datenschutz- und Sicherheitspraktiken können je nach App-Version, Verwendung, Region und Alter des Nutzers variieren."</string> <string name="permission_rationale_location_settings_title" msgid="7204145004850190953">"Deine Standortdaten"</string> - <string name="permission_rationale_permission_settings_message" msgid="631286040979660267">"Du kannst den Zugriff dieser App in den "<annotation id="link">"Datenschutzeinstellungen"</annotation>" ändern"</string> + <string name="permission_rationale_permission_settings_message" msgid="631286040979660267">"Du kannst den Zugriff dieser App in den "<annotation id="link">"Datenschutzeinstellungen"</annotation>" ändern"</string> <string name="permission_rationale_purpose_app_functionality" msgid="8397736681065841405">"Funktionen der App"</string> <string name="permission_rationale_purpose_analytics" msgid="2070800501189620712">"Analytics"</string> <string name="permission_rationale_purpose_developer_communications" msgid="6453047018892062374">"Mitteilungen des Entwicklers"</string> @@ -648,4 +655,26 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Änderungen bei der Datenweitergabepraxis"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Bei einigen Apps hat sich die Art der Weitergabe deiner Standortdaten geändert"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Einstellungen"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Zugriff: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Zugriff: gestern, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Zugriff: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Dein Einmalpasswort lautet 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Eingeschränkte Einstellung"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Aus Sicherheitsgründen ist diese Einstellung derzeit nicht verfügbar."</string> + <!-- no translation found for enhanced_confirmation_dialog_title_permission (2149144789394238266) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_permission (3150778951946468945) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_title_role (1737023798483772780) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_role (6369601947905234551) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_title_settings_default (1858092969721041576) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_settings_default (6911632348359332981) --> + <skip /> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Weitere Informationen"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Ok"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Berechtigungsanfrage unterdrückt"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Diese App fordert zusätzliche Berechtigungen an – in einer Streamingsitzung können jedoch keine Berechtigungen gewährt werden. Erteile zuerst die Berechtigung auf deinem Smartphone."</string> </resources> diff --git a/PermissionController/res/values-el-car/strings.xml b/PermissionController/res/values-el-car/strings.xml index 605dfdf64..762f42d2b 100644 --- a/PermissionController/res/values-el-car/strings.xml +++ b/PermissionController/res/values-el-car/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="unused_apps_page_summary" msgid="7505839764289846511">"Εάν μια εφαρμογή δεν χρησιμοποιηθεί για μερικούς μήνες:\n\n• Οι άδειες καταργούνται για την προστασία των δεδομένων σας\n• Τα προσωρινά αρχεία καταργούνται για την απελευθέρωση χώρου"</string> + <string name="unused_apps_page_summary" msgid="7505839764289846511">"Εάν μια εφαρμογή δεν χρησιμοποιηθεί για μερικούς μήνες:\n\n• Οι άδειες καταργούνται για την προστασία των δεδομένων σας\n• Τα προσωρινά αρχεία καταργούνται για την αποδέσμευση χώρου"</string> </resources> diff --git a/PermissionController/res/values-el-v34/strings.xml b/PermissionController/res/values-el-v34/strings.xml index 0c8541787..b7486d405 100644 --- a/PermissionController/res/values-el-v34/strings.xml +++ b/PermissionController/res/values-el-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Διαχείριση της πρόσβασης των εφαρμογών στα δεδομένα υγείας"</string> <string name="location_settings" msgid="8863940440881290182">"Πρόσβαση στην τοποθεσία"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Για εφαρμογές και υπηρεσίες. Εάν είναι απενεργοποιημένη αυτή η ρύθμιση, τα δεδομένα μικροφώνου ενδέχεται να κοινοποιούνται όταν καλείτε έναν αριθμό έκτακτης ανάγκης."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Για εφαρμογές και υπηρεσίες"</string> </resources> diff --git a/PermissionController/res/values-el-watch/strings.xml b/PermissionController/res/values-el-watch/strings.xml index 05063253d..6f461e93d 100644 --- a/PermissionController/res/values-el-watch/strings.xml +++ b/PermissionController/res/values-el-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Αδυναμία αλλαγής"</string> <string name="generic_yes" msgid="2489207724988649846">"Ναι"</string> <string name="generic_cancel" msgid="2631708607129269698">"Ακύρωση"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Να επιτρέπεται πάντα"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Με τη χρήση της εφαρμογής"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Να επιτρέπεται πάντα"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Με τη χρήση της εφαρμογής"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Να επιτρέπεται πάντα"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Με τη χρήση της εφαρμογής"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Να επιτρέπεται πάντα"</string> </resources> diff --git a/PermissionController/res/values-el/strings.xml b/PermissionController/res/values-el/strings.xml index a8039d2d9..1372370af 100644 --- a/PermissionController/res/values-el/strings.xml +++ b/PermissionController/res/values-el/strings.xml @@ -54,7 +54,7 @@ <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Κατά τη χρήση της εφαρμογής"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"Αλλαγή σε ακριβή τοποθεσία"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"Διατήρηση κατά προσέγγιση τοποθεσίας"</string> - <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"Μόνο αυτήν τη φορά"</string> + <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"Μόνο αυτή τη φορά"</string> <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"Να επιτρέπεται πάντα"</string> <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"Να επιτρέπεται η διαχείριση όλων των αρχείων"</string> <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"Να επιτρέπεται η πρόσβαση σε αρχεία μέσων"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Όλες οι άδειες"</string> <string name="other_permissions" msgid="2901186127193849594">"Άλλες δυνατότητες εφαρμογής"</string> <string name="permission_request_title" msgid="8790310151025020126">"Αίτημα άδειας"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Οι ενέργειες εγκατάστασης/απεγκατάστασης δεν υποστηρίζονται στο Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Επιλέξτε σε τι θα έχει πρόσβαση η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ενημερώθηκε. Επιλέξτε σε τι θα έχει πρόσβαση αυτή η εφαρμογή."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Ακύρωση"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Όταν είναι απενεργοποιημένη η ακριβής τοποθεσία, οι εφαρμογές μπορούν να έχουν πρόσβαση στην κατά προσέγγιση τοποθεσία σας"</string> <string name="app_permission_title" msgid="2090897901051370711">"Άδεια - <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Πρόσβαση σε <xliff:g id="PERM">%1$s</xliff:g> για αυτή την εφαρμογή"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Πρόσβαση στην άδεια <xliff:g id="PERM">%1$s</xliff:g> για αυτή την εφαρμογή στη συσκευή <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Εμφάνιση όλων των αδειών της εφαρμογής <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Εμφάνιση όλων των εφαρμογών με αυτή την άδεια"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Εμφάνιση χρήσης μικροφώνου βοηθού"</string> <string name="unused_apps_category_title" msgid="2988455616845243901">"Ρυθμίσεις μη χρησιμοποιούμενων εφαρμογών"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"Καταργήστε τις άδειες, εάν η εφαρμογή δεν χρησιμοποιείται."</string> - <string name="unused_apps_label" msgid="2595428768404901064">"Κατάργηση αδειών και απελευθέρωση χώρου"</string> + <string name="unused_apps_label" msgid="2595428768404901064">"Κατάργηση αδειών και αποδέσμευση χώρου"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Παύση δραστηριότητας αδρανούς εφαρμογής"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Διαχείρ. εφαρμ. αν δεν χρησιμοποιείται"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Κατάργηση αδειών, διαγραφή προσωρινών αρχείων και διακοπή ειδοποιήσεων"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Κατάργηση αδειών, διαγραφή προσωρινών αρχείων, διακοπή ειδοποιήσεων και αρχειοθέτηση της εφαρμογής"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Για την προστασία των δεδομένων σας, οι άδειες για αυτή την εφαρμογή θα καταργηθούν εάν η εφαρμογή δεν χρησιμοποιηθεί για μερικούς μήνες."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Για την προστασία των δεδομένων σας, εάν δεν έχει χρησιμοποιηθεί η εφαρμογή για μερικούς μήνες, οι παρακάτω άδειες θα καταργηθούν: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Για την προστασία των δεδομένων σας, έχουν καταργηθεί οι άδειες εφαρμογών που δεν έχετε χρησιμοποιήσει κατά τους τελευταίους μήνες."</string> @@ -221,8 +222,8 @@ <string name="auto_revoked_app_summary_two" msgid="1910545340763709389">"Καταργήθηκαν οι άδειες <xliff:g id="PERMISSION_NAME_0">%1$s</xliff:g> και <xliff:g id="PERMISSION_NAME_1">%2$s</xliff:g>"</string> <string name="auto_revoked_app_summary_many" msgid="5930976230827378798">"Καταργήθηκε η άδεια <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> και <xliff:g id="NUMBER">%2$s</xliff:g> ακόμη άδειες"</string> <string name="unused_apps_page_title" msgid="6986983535677572559">"Εφαρμογές που δεν χρησιμοποιούνται"</string> - <string name="unused_apps_page_summary" msgid="1867593913217272155">"Εάν μια εφαρμογή δεν χρησιμοποιηθεί για λίγους μήνες:\n\n• Οι άδειες καταργούνται για την προστασία των δεδομένων σας\n• Οι ειδοποιήσεις διακόπτονται για την εξοικονόμηση μπαταρίας\n• Τα προσωρινά αρχεία καταργούνται για την απελευθέρωση χώρου\n\nΓια να επιτρέψετε ξανά τις άδειες και τις ειδοποιήσεις, ανοίξτε την εφαρμογή."</string> - <string name="unused_apps_page_tv_summary" msgid="2624911608663778308">"Εάν μια εφαρμογή δεν χρησιμοποιηθεί για έναν μήνα:\n\n• Οι άδειες καταργούνται για την προστασία των δεδομένων σας\n• Τα προσωρινά αρχεία καταργούνται για την απελευθέρωση χώρου\n\nΓια να επιτρέψετε ξανά τις άδειες, ανοίξτε την εφαρμογή."</string> + <string name="unused_apps_page_summary" msgid="1867593913217272155">"Εάν μια εφαρμογή δεν χρησιμοποιηθεί για λίγους μήνες:\n\n• Οι άδειες καταργούνται για την προστασία των δεδομένων σας\n• Οι ειδοποιήσεις διακόπτονται για την εξοικονόμηση μπαταρίας\n• Τα προσωρινά αρχεία καταργούνται για την αποδέσμευση χώρου\n\nΓια να επιτρέψετε ξανά τις άδειες και τις ειδοποιήσεις, ανοίξτε την εφαρμογή."</string> + <string name="unused_apps_page_tv_summary" msgid="2624911608663778308">"Εάν μια εφαρμογή δεν χρησιμοποιηθεί για έναν μήνα:\n\n• Οι άδειες καταργούνται για την προστασία των δεδομένων σας\n• Τα προσωρινά αρχεία καταργούνται για την αποδέσμευση χώρου\n\nΓια να επιτρέψετε ξανά τις άδειες, ανοίξτε την εφαρμογή."</string> <string name="last_opened_category_title" msgid="8796557894614236128">"{count,plural, =1{Τελευταίο άνοιγμα πάνω από # μήνα πριν}other{Τελευταίο άνοιγμα πάνω από # μήνες πριν}}"</string> <string name="last_opened_summary" msgid="5248984030024968808">"Τελευταίο άνοιγμα εφαρμογής <xliff:g id="DATE">%s</xliff:g>"</string> <string name="last_opened_summary_short" msgid="1646067226191176825">"Τελευταίο άνοιγμα <xliff:g id="DATE">%s</xliff:g>"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Επιτρέπεται η διαχείριση όλων των αρχείων"</string> <string name="ask_header" msgid="2633816846459944376">"Ερώτηση κάθε φορά"</string> <string name="denied_header" msgid="903209608358177654">"Δεν επιτρέπεται"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> στη συσκευή <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Δείτε περισσότερες εφαρμογές με πρόσβαση σε όλα τα αρχεία"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ημέρα}other{# ημέρες}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ώρα}other{# ώρες}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Εφαρμογή σημειώσεων"</string> <string name="role_notes_description" msgid="8496852798616883551">"Εφαρμογές που σας επιτρέπουν να κρατάτε σημειώσεις στη συσκευή σας"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"σημειώσεις"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Προεπιλ. εφαρμογή πορτοφολιού"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Εφαρμογή πορτοφολιού"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Οι εφαρμογές πορτοφολιού μπορούν να αποθηκεύσουν πιστωτικές κάρτες και κάρτες επιβράβευσης αφοσιωμένων πελατών, κλειδιά αυτοκινήτου και άλλα στοιχεία για να σας βοηθήσουν με διάφορες μορφές συναλλαγών."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Ορισμός της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g> ως προεπιλεγμένης εφαρμογής πορτοφολιού;"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Δεν απαιτούνται άδειες"</string> <string name="request_role_current_default" msgid="738722892438247184">"Τρέχουσα προεπιλογή"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Να μην ερωτηθώ ξανά"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Προεπιλογή"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Ενημερώσεις κοινοποίησης δεδομένων"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Ορισμένες εφαρμογές άλλαξαν τον τρόπο με τον οποίο ενδέχεται να κοινοποιούν τα δεδομένα τοποθεσίας σας"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Ρυθμίσεις"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Πρόσβαση στις <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Πρόσβαση χθες, στις <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Πρόσβαση στις <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Ο κωδικός πρόσβασης μίας χρήσης είναι 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Περιορισμένη ρύθμιση"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Για την ασφάλειά σας, αυτή η ρύθμιση δεν είναι διαθέσιμη αυτή τη στιγμή."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Απορρίφθηκε η πρόσβαση της εφαρμογής στην άδεια <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Η εφαρμογή ζήτησε πρόσβαση σε μια άδεια πρόσβασης σε ευαίσθητες πληροφορίες, γεγονός που μπορεί να θέσει σε κίνδυνο τα προσωπικά και οικονομικά στοιχεία σας.<xliff:g id="ID_1"><br><br></xliff:g>Είναι πιθανό η εφαρμογή να μην λειτουργεί σωστά χωρίς αυτή την περιορισμένη άδεια. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Μάθετε πώς μπορείτε να επιτρέψετε την πρόσβαση</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Δεν επιτράπηκε στην εφαρμογή να οριστεί ως η προεπιλεγμένη <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Η εφαρμογή ζήτησε πρόσβαση σε άδειες πρόσβασης σε ευαίσθητες πληροφορίες, γεγονός που μπορεί να θέσει σε κίνδυνο τα προσωπικά και οικονομικά στοιχεία σας.<xliff:g id="ID_1"><br><br></xliff:g>Είναι πιθανό η εφαρμογή να μην λειτουργεί σωστά χωρίς αυτές τις περιορισμένες άδειες. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Μάθετε πώς μπορείτε να επιτρέψετε την πρόσβαση</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Απορρίφθηκε η πρόσβαση της εφαρμογής"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Η πρόσβαση σε αυτή την άδεια μπορεί να θέσει σε κίνδυνο τα προσωπικά και οικονομικά στοιχεία σας.<xliff:g id="ID_1"><br><br></xliff:g>Είναι πιθανό η εφαρμογή να μην λειτουργεί σωστά χωρίς αυτή την περιορισμένη άδεια. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Μάθετε πώς μπορείτε να επιτρέψετε την πρόσβαση</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Μάθετε περισσότερα"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ΟΚ"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Το αίτημα άδειας ανεστάλη"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Αυτή η εφαρμογή ζητά πρόσθετες άδειες, αλλά οι άδειες δεν μπορούν να εκχωρηθούν σε μια περίοδο σύνδεσης ροής. Εκχωρήστε πρώτα την άδεια στο τηλέφωνό σας."</string> </resources> diff --git a/PermissionController/res/values-en-rAU-v34/strings.xml b/PermissionController/res/values-en-rAU-v34/strings.xml index 4800f8a91..f16d34825 100644 --- a/PermissionController/res/values-en-rAU-v34/strings.xml +++ b/PermissionController/res/values-en-rAU-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Manage app access to health data"</string> <string name="location_settings" msgid="8863940440881290182">"Location access"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"For apps and services. If this setting is off, microphone data may still be shared when you call an emergency number"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"For apps and services"</string> </resources> diff --git a/PermissionController/res/values-en-rAU-watch/strings.xml b/PermissionController/res/values-en-rAU-watch/strings.xml index 70643f521..e3f48cb2c 100644 --- a/PermissionController/res/values-en-rAU-watch/strings.xml +++ b/PermissionController/res/values-en-rAU-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Can\'t be changed"</string> <string name="generic_yes" msgid="2489207724988649846">"Yes"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancel"</string> + <string name="permission_access_always" msgid="2107115233573823032">"All the time"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"While using app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"All the time"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"While using app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"All the time"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"While using app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"All the time"</string> </resources> diff --git a/PermissionController/res/values-en-rAU/strings.xml b/PermissionController/res/values-en-rAU/strings.xml index 6fb7994a8..d9cdeb780 100644 --- a/PermissionController/res/values-en-rAU/strings.xml +++ b/PermissionController/res/values-en-rAU/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"All permissions"</string> <string name="other_permissions" msgid="2901186127193849594">"Other app capabilities"</string> <string name="permission_request_title" msgid="8790310151025020126">"Permission request"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Install/Uninstall actions not supported on Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what access to allow this app."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancel"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"When precise location is off, apps can access your approximate location"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> permission"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> access for this app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> access for this app on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"See all <xliff:g id="APP">%1$s</xliff:g> permissions"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"See all apps with this permission"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Show Assistant microphone usage"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Remove permissions if app isn’t used"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remove permissions and free up space"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pause app activity if unused"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Manage app if unused"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remove permissions, delete temporary files and stop notifications"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove permissions, delete temporary files, stop notifications and archive the app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"To protect your data, permissions for this app will be removed if the app is unused for a few months."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"To protect your data, if the app is unused for a few months, the following permissions will be removed: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"To protect your data, permissions have been removed from apps that you haven’t used in a few months."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Allowed to manage all files"</string> <string name="ask_header" msgid="2633816846459944376">"Ask every time"</string> <string name="denied_header" msgid="903209608358177654">"Not allowed"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"See more apps that can access all files"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 day}other{# days}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hour}other{# hours}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notes app"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps that allow you to take notes on your device"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Default wallet app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Wallet apps can store your credit and loyalty cards, car keys and other things to help with various forms of transactions."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Set <xliff:g id="APP_NAME">%1$s</xliff:g> as your default wallet app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No permissions needed"</string> <string name="request_role_current_default" msgid="738722892438247184">"Current default"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Don\'t ask again"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Set as default"</string> @@ -560,7 +567,7 @@ <string name="safety_status_preference_title_and_summary_content_description" msgid="3511373256505058464">"Security and privacy status. <xliff:g id="OVERALL_SAFETY_STATUS">%1$s</xliff:g>. <xliff:g id="SUMMARY_OF_DEVICE_STATUS">%2$s</xliff:g>"</string> <string name="security_settings" msgid="3808106921175271317">"Security settings"</string> <string name="sensor_permissions_qs" msgid="1022267900031317472">"Permissions"</string> - <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Security & privacy"</string> + <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Security and privacy"</string> <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Check status"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Your privacy controls"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"More settings"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Data sharing updates"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Some apps changed the way that they may share your location data"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Settings"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Accessed <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Accessed yesterday <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Accessed <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Your one-time password is 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Restricted setting"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"For your security, this setting is currently unavailable."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"App was denied access to <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"The app requested access to a sensitive permission which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"App was denied access to be default <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"The app requested access to sensitive permissions which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without these restricted permissions. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"App was denied access"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Access to this permission can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Learn more"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Permission request suppressed"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"This app is requesting additional permissions, but permissions can\'t be granted in a streaming session. Grant the permission on your phone first."</string> </resources> diff --git a/PermissionController/res/values-en-rCA-v34/strings.xml b/PermissionController/res/values-en-rCA-v34/strings.xml index 4800f8a91..f16d34825 100644 --- a/PermissionController/res/values-en-rCA-v34/strings.xml +++ b/PermissionController/res/values-en-rCA-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Manage app access to health data"</string> <string name="location_settings" msgid="8863940440881290182">"Location access"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"For apps and services. If this setting is off, microphone data may still be shared when you call an emergency number"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"For apps and services"</string> </resources> diff --git a/PermissionController/res/values-en-rCA-watch/strings.xml b/PermissionController/res/values-en-rCA-watch/strings.xml index adecb65b9..aa97f28cc 100644 --- a/PermissionController/res/values-en-rCA-watch/strings.xml +++ b/PermissionController/res/values-en-rCA-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Can\'t be changed"</string> <string name="generic_yes" msgid="2489207724988649846">"Yes"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancel"</string> + <string name="permission_access_always" msgid="2107115233573823032">"All the time"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"While using app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"All the time"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"While using app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"All the time"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"While using app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"All the time"</string> </resources> diff --git a/PermissionController/res/values-en-rCA/strings.xml b/PermissionController/res/values-en-rCA/strings.xml index a01a0cef2..87e1b1516 100644 --- a/PermissionController/res/values-en-rCA/strings.xml +++ b/PermissionController/res/values-en-rCA/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"All permissions"</string> <string name="other_permissions" msgid="2901186127193849594">"Other app capabilities"</string> <string name="permission_request_title" msgid="8790310151025020126">"Permission request"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Install/Uninstall actions not supported on Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what to allow this app to access."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancel"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"When precise location is off, apps can access your approximate location"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> permission"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> access for this app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> access for this app on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"See all <xliff:g id="APP">%1$s</xliff:g> permissions"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"See all apps with this permission"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Show assistant microphone usage"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Remove permissions if app isn’t used"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remove permissions and free up space"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pause app activity if unused"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Manage app if unused"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remove permissions, delete temporary files, and stop notifications"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove permissions, delete temporary files, stop notifications, and archive the app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"To protect your data, permissions for this app will be removed if the app is unused for a few months."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"To protect your data, if the app is unused for a few months, the following permissions will be removed: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"To protect your data, permissions have been removed from apps that you haven’t used in a few months."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Allowed to manage all files"</string> <string name="ask_header" msgid="2633816846459944376">"Ask every time"</string> <string name="denied_header" msgid="903209608358177654">"Not allowed"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"See more apps that can access all files"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 day}other{# days}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hour}other{# hours}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notes app"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps that allow you to take notes on your device"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Default wallet app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Wallet apps can store your credit and loyalty cards, car keys and other things to help with various forms of transactions."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Set <xliff:g id="APP_NAME">%1$s</xliff:g> as your default wallet app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No permissions needed"</string> <string name="request_role_current_default" msgid="738722892438247184">"Current default"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Don’t ask again"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Set as default"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Data sharing updates"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Some apps changed the way they may share your location data"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Settings"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Accessed <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Accessed yesterday <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Accessed <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Your one time password is 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Restricted setting"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"For your security, this setting is currently unavailable."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"App was denied access to <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"The app requested access to a sensitive permission which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"App was denied access to be default <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"The app requested access to sensitive permissions which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible the app won\'t work properly without these restricted permissions. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"App was denied access"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Access to this permission can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Learn more"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Permission request suppressed"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your phone first."</string> </resources> diff --git a/PermissionController/res/values-en-rGB-v34/strings.xml b/PermissionController/res/values-en-rGB-v34/strings.xml index 4800f8a91..f16d34825 100644 --- a/PermissionController/res/values-en-rGB-v34/strings.xml +++ b/PermissionController/res/values-en-rGB-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Manage app access to health data"</string> <string name="location_settings" msgid="8863940440881290182">"Location access"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"For apps and services. If this setting is off, microphone data may still be shared when you call an emergency number"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"For apps and services"</string> </resources> diff --git a/PermissionController/res/values-en-rGB-watch/strings.xml b/PermissionController/res/values-en-rGB-watch/strings.xml index 70643f521..e3f48cb2c 100644 --- a/PermissionController/res/values-en-rGB-watch/strings.xml +++ b/PermissionController/res/values-en-rGB-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Can\'t be changed"</string> <string name="generic_yes" msgid="2489207724988649846">"Yes"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancel"</string> + <string name="permission_access_always" msgid="2107115233573823032">"All the time"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"While using app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"All the time"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"While using app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"All the time"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"While using app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"All the time"</string> </resources> diff --git a/PermissionController/res/values-en-rGB/strings.xml b/PermissionController/res/values-en-rGB/strings.xml index bfaca7355..4d7cb00a2 100644 --- a/PermissionController/res/values-en-rGB/strings.xml +++ b/PermissionController/res/values-en-rGB/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"All permissions"</string> <string name="other_permissions" msgid="2901186127193849594">"Other app capabilities"</string> <string name="permission_request_title" msgid="8790310151025020126">"Permission request"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Install/Uninstall actions not supported on Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what access to allow this app."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancel"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"When precise location is off, apps can access your approximate location"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> permission"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> access for this app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> access for this app on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"See all <xliff:g id="APP">%1$s</xliff:g> permissions"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"See all apps with this permission"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Show Assistant microphone usage"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Remove permissions if app isn’t used"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remove permissions and free up space"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pause app activity if unused"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Manage app if unused"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remove permissions, delete temporary files and stop notifications"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove permissions, delete temporary files, stop notifications and archive the app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"To protect your data, permissions for this app will be removed if the app is unused for a few months."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"To protect your data, if the app is unused for a few months, the following permissions will be removed: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"To protect your data, permissions have been removed from apps that you haven’t used in a few months."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Allowed to manage all files"</string> <string name="ask_header" msgid="2633816846459944376">"Ask every time"</string> <string name="denied_header" msgid="903209608358177654">"Not allowed"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"See more apps that can access all files"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 day}other{# days}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hour}other{# hours}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notes app"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps that allow you to take notes on your device"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Default wallet app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Wallet apps can store your credit and loyalty cards, car keys and other things to help with various forms of transactions."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Set <xliff:g id="APP_NAME">%1$s</xliff:g> as your default wallet app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No permissions needed"</string> <string name="request_role_current_default" msgid="738722892438247184">"Current default"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Don\'t ask again"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Set as default"</string> @@ -560,7 +567,7 @@ <string name="safety_status_preference_title_and_summary_content_description" msgid="3511373256505058464">"Security and privacy status. <xliff:g id="OVERALL_SAFETY_STATUS">%1$s</xliff:g>. <xliff:g id="SUMMARY_OF_DEVICE_STATUS">%2$s</xliff:g>"</string> <string name="security_settings" msgid="3808106921175271317">"Security settings"</string> <string name="sensor_permissions_qs" msgid="1022267900031317472">"Permissions"</string> - <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Security & privacy"</string> + <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Security and privacy"</string> <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Check status"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Your privacy controls"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"More settings"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Data sharing updates"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Some apps changed the way that they may share your location data"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Settings"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Accessed <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Accessed yesterday <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Accessed <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Your one-time password is 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Restricted setting"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"For your security, this setting is currently unavailable."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"App was denied access to <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"The app requested access to a sensitive permission which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"App was denied access to be default <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"The app requested access to sensitive permissions which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without these restricted permissions. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"App was denied access"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Access to this permission can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Learn more"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Permission request suppressed"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"This app is requesting additional permissions, but permissions can\'t be granted in a streaming session. Grant the permission on your phone first."</string> </resources> diff --git a/PermissionController/res/values-en-rIN-v34/strings.xml b/PermissionController/res/values-en-rIN-v34/strings.xml index 4800f8a91..f16d34825 100644 --- a/PermissionController/res/values-en-rIN-v34/strings.xml +++ b/PermissionController/res/values-en-rIN-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Manage app access to health data"</string> <string name="location_settings" msgid="8863940440881290182">"Location access"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"For apps and services. If this setting is off, microphone data may still be shared when you call an emergency number"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"For apps and services"</string> </resources> diff --git a/PermissionController/res/values-en-rIN-watch/strings.xml b/PermissionController/res/values-en-rIN-watch/strings.xml index 70643f521..e3f48cb2c 100644 --- a/PermissionController/res/values-en-rIN-watch/strings.xml +++ b/PermissionController/res/values-en-rIN-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Can\'t be changed"</string> <string name="generic_yes" msgid="2489207724988649846">"Yes"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancel"</string> + <string name="permission_access_always" msgid="2107115233573823032">"All the time"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"While using app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"All the time"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"While using app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"All the time"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"While using app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"All the time"</string> </resources> diff --git a/PermissionController/res/values-en-rIN/strings.xml b/PermissionController/res/values-en-rIN/strings.xml index bfaca7355..4d7cb00a2 100644 --- a/PermissionController/res/values-en-rIN/strings.xml +++ b/PermissionController/res/values-en-rIN/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"All permissions"</string> <string name="other_permissions" msgid="2901186127193849594">"Other app capabilities"</string> <string name="permission_request_title" msgid="8790310151025020126">"Permission request"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Install/Uninstall actions not supported on Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what access to allow this app."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancel"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"When precise location is off, apps can access your approximate location"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> permission"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> access for this app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> access for this app on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"See all <xliff:g id="APP">%1$s</xliff:g> permissions"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"See all apps with this permission"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Show Assistant microphone usage"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Remove permissions if app isn’t used"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remove permissions and free up space"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pause app activity if unused"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Manage app if unused"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remove permissions, delete temporary files and stop notifications"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove permissions, delete temporary files, stop notifications and archive the app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"To protect your data, permissions for this app will be removed if the app is unused for a few months."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"To protect your data, if the app is unused for a few months, the following permissions will be removed: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"To protect your data, permissions have been removed from apps that you haven’t used in a few months."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Allowed to manage all files"</string> <string name="ask_header" msgid="2633816846459944376">"Ask every time"</string> <string name="denied_header" msgid="903209608358177654">"Not allowed"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"See more apps that can access all files"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 day}other{# days}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hour}other{# hours}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notes app"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps that allow you to take notes on your device"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Default wallet app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Wallet apps can store your credit and loyalty cards, car keys and other things to help with various forms of transactions."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Set <xliff:g id="APP_NAME">%1$s</xliff:g> as your default wallet app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No permissions needed"</string> <string name="request_role_current_default" msgid="738722892438247184">"Current default"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Don\'t ask again"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Set as default"</string> @@ -560,7 +567,7 @@ <string name="safety_status_preference_title_and_summary_content_description" msgid="3511373256505058464">"Security and privacy status. <xliff:g id="OVERALL_SAFETY_STATUS">%1$s</xliff:g>. <xliff:g id="SUMMARY_OF_DEVICE_STATUS">%2$s</xliff:g>"</string> <string name="security_settings" msgid="3808106921175271317">"Security settings"</string> <string name="sensor_permissions_qs" msgid="1022267900031317472">"Permissions"</string> - <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Security & privacy"</string> + <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Security and privacy"</string> <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Check status"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Your privacy controls"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"More settings"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Data sharing updates"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Some apps changed the way that they may share your location data"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Settings"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Accessed <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Accessed yesterday <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Accessed <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Your one-time password is 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Restricted setting"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"For your security, this setting is currently unavailable."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"App was denied access to <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"The app requested access to a sensitive permission which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"App was denied access to be default <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"The app requested access to sensitive permissions which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without these restricted permissions. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"App was denied access"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Access to this permission can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible that the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Learn more"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Permission request suppressed"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"This app is requesting additional permissions, but permissions can\'t be granted in a streaming session. Grant the permission on your phone first."</string> </resources> diff --git a/PermissionController/res/values-en-rXC-v34/strings.xml b/PermissionController/res/values-en-rXC-v34/strings.xml index 525a410b1..91d6fc736 100644 --- a/PermissionController/res/values-en-rXC-v34/strings.xml +++ b/PermissionController/res/values-en-rXC-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Manage app access to health data"</string> <string name="location_settings" msgid="8863940440881290182">"Location access"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"For apps and services. If this setting is off, microphone data may still be shared when you call an emergency number"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"For apps and services"</string> </resources> diff --git a/PermissionController/res/values-en-rXC-watch/strings.xml b/PermissionController/res/values-en-rXC-watch/strings.xml index 75a8de56f..c8631b66a 100644 --- a/PermissionController/res/values-en-rXC-watch/strings.xml +++ b/PermissionController/res/values-en-rXC-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Can\'t be changed"</string> <string name="generic_yes" msgid="2489207724988649846">"Yes"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancel"</string> + <string name="permission_access_always" msgid="2107115233573823032">"All the time"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"While using app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"All the time"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"While using app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"All the time"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"While using app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"All the time"</string> </resources> diff --git a/PermissionController/res/values-en-rXC/strings.xml b/PermissionController/res/values-en-rXC/strings.xml index 34a84175e..9923d28d9 100644 --- a/PermissionController/res/values-en-rXC/strings.xml +++ b/PermissionController/res/values-en-rXC/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"All permissions"</string> <string name="other_permissions" msgid="2901186127193849594">"Other app capabilities"</string> <string name="permission_request_title" msgid="8790310151025020126">"Permission request"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Install/Uninstall actions not supported on Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what to allow this app to access."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancel"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"When precise location is off, apps can access your approximate location"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> permission"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> access for this app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> access for this app on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"See all <xliff:g id="APP">%1$s</xliff:g> permissions"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"See all apps with this permission"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Show assistant microphone usage"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Remove permissions if app isn’t used"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remove permissions and free up space"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pause app activity if unused"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Manage app if unused"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remove permissions, delete temporary files, and stop notifications"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove permissions, delete temporary files, stop notifications, and archive the app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"To protect your data, permissions for this app will be removed if the app is unused for a few months."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"To protect your data, if the app is unused for a few months, the following permissions will be removed: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"To protect your data, permissions have been removed from apps that you haven’t used in a few months."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Allowed to manage all files"</string> <string name="ask_header" msgid="2633816846459944376">"Ask every time"</string> <string name="denied_header" msgid="903209608358177654">"Not allowed"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> on <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"See more apps that can access all files"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 day}other{# days}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hour}other{# hours}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notes app"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps that allow you to take notes on your device"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Default wallet app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Wallet apps can store your credit and loyalty cards, car keys and other things to help with various forms of transactions."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Set <xliff:g id="APP_NAME">%1$s</xliff:g> as your default wallet app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No permissions needed"</string> <string name="request_role_current_default" msgid="738722892438247184">"Current default"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Don’t ask again"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Set as default"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Data sharing updates"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Some apps changed the way they may share your location data"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Settings"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Accessed <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Accessed yesterday <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Accessed <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Your one time password is 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Restricted setting"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"For your security, this setting is currently unavailable."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"App was denied access to <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"The app requested access to a sensitive permission which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"App was denied access to be default <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"The app requested access to sensitive permissions which can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible the app won\'t work properly without these restricted permissions. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"App was denied access"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Access to this permission can put your personal and financial info at risk.<xliff:g id="ID_1"><br><br></xliff:g>It\'s possible the app won\'t work properly without this restricted permission. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Learn how to allow access</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Learn more"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Permission request suppressed"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your phone first."</string> </resources> diff --git a/PermissionController/res/values-es-rUS-v34/strings.xml b/PermissionController/res/values-es-rUS-v34/strings.xml index e180c0b7c..31585916a 100644 --- a/PermissionController/res/values-es-rUS-v34/strings.xml +++ b/PermissionController/res/values-es-rUS-v34/strings.xml @@ -22,6 +22,5 @@ <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> <string name="health_connect_summary" msgid="815473513776882296">"Administra el acceso de las apps a Health Connect"</string> <string name="location_settings" msgid="8863940440881290182">"Acceso a la ubicación"</string> - <string name="mic_toggle_description" msgid="1504101620086616040">"Para apps y servicios. Aunque se desactive este parámetro de configuración, es posible que se sigan compartiendo los datos del micrófono cuando llames a un número de emergencia."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Para apps y servicios"</string> + <string name="mic_toggle_description" msgid="1504101620086616040">"Para apps y servicios. Aunque se desactive este parámetro de configuración, es posible que se sigan compartiendo los datos del micrófono cuando llames a un número de emergencia"</string> </resources> diff --git a/PermissionController/res/values-es-rUS-watch/strings.xml b/PermissionController/res/values-es-rUS-watch/strings.xml index 25fa4d5f5..ce3aa4a86 100644 --- a/PermissionController/res/values-es-rUS-watch/strings.xml +++ b/PermissionController/res/values-es-rUS-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"No puedes cambiar"</string> <string name="generic_yes" msgid="2489207724988649846">"Sí"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancelar"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Todo el tiempo"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Con la app en uso"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Todo el tiempo"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Con la app en uso"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Todo el tiempo"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Con la app en uso"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Todo el tiempo"</string> </resources> diff --git a/PermissionController/res/values-es-rUS/strings.xml b/PermissionController/res/values-es-rUS/strings.xml index ba8386062..f1dc3b331 100644 --- a/PermissionController/res/values-es-rUS/strings.xml +++ b/PermissionController/res/values-es-rUS/strings.xml @@ -34,7 +34,7 @@ <string name="grant_dialog_button_more_info" msgid="213350268561945193">"Más información"</string> <string name="grant_dialog_button_allow_all" msgid="5939066403732409516">"Permitir todo"</string> <string name="grant_dialog_button_always_allow_all" msgid="1719900027660252167">"Permitir todo siempre"</string> - <string name="grant_dialog_button_allow_limited_access" msgid="5713551784422137594">"Permite el acceso limitado"</string> + <string name="grant_dialog_button_allow_limited_access" msgid="5713551784422137594">"Permitir el acceso limitado"</string> <string name="grant_dialog_button_allow_selected_photos" msgid="5497042471576153842">"Seleccionar fotos y videos"</string> <string name="grant_dialog_button_allow_more_selected_photos" msgid="5145657877588697709">"Seleccionar más"</string> <string name="grant_dialog_button_dont_select_more" msgid="6643552729129461268">"No seleccionar más"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Todos los permisos"</string> <string name="other_permissions" msgid="2901186127193849594">"Otras funciones de la app"</string> <string name="permission_request_title" msgid="8790310151025020126">"Solicitud de permiso"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear no admite las acciones de instalación y desinstalación"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Selecciona los permisos de acceso para <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Se actualizó <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Selecciona los permisos de acceso para esta app."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancelar"</string> @@ -195,10 +193,11 @@ <string name="app_permission_button_deny" msgid="6016454069832050300">"No permitir"</string> <string name="precise_image_description" msgid="6349638632303619872">"Ubicación precisa"</string> <string name="approximate_image_description" msgid="938803699637069884">"Ubicación aproximada"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Usar la ubicación precisa"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Ubicación precisa"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Cuando la ubicación precisa está desactivada, las apps acceden a la ubicación aproximada"</string> <string name="app_permission_title" msgid="2090897901051370711">"Permiso de <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Acceso a <xliff:g id="PERM">%1$s</xliff:g> para esta app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Acceso a <xliff:g id="PERM">%1$s</xliff:g> para esta app en <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ver todos los permisos de <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Ver todas las apps que tienen este permiso"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostrar el uso del micrófono del Asistente"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Quitar los permisos si la app no se usa"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Quitar permisos y liberar espacio"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausar actividad en la app si no se usa"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Administrar la app si no se usa"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Quitar permisos, borrar archivos temporales y detener notificaciones"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Quita permisos, borra archivos temporales, detiene notificaciones y archiva la app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para proteger tus datos, se quitarán los permisos de esta app si no la usas durante varios meses."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para proteger tus datos, si no usas la app durante varios meses, se quitarán los siguientes permisos: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para proteger tus datos, se quitaron los permisos de las apps que están en desuso hace varios meses."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Pueden administrar todos los archivos"</string> <string name="ask_header" msgid="2633816846459944376">"Preguntar siempre"</string> <string name="denied_header" msgid="903209608358177654">"Sin permiso"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> en <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Ver más apps que pueden acceder a todos los archivos"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 día}many{# días}other{# días}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hora}many{# horas}other{# horas}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"App de notas"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps que te permiten tomar notas en tu dispositivo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notas"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Billetera predeterminada"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"App de billetera"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Las apps de billetera pueden almacenar tus tarjetas de crédito y lealtad, las llaves de tu vehículo y otros elementos para ayudarte con los diferentes tipos de transacciones."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"¿Quieres configurar <xliff:g id="APP_NAME">%1$s</xliff:g> como tu app de billetera predeterminada?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No se requieren permisos"</string> <string name="request_role_current_default" msgid="738722892438247184">"App predeterminada actualmente"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"No volver a preguntar"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Hacer predeterminada"</string> @@ -448,7 +455,7 @@ <string name="incident_report_dialog_text" msgid="5675553296891757523">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> solicita subir un informe de errores de este dispositivo generado el <xliff:g id="DATE">%2$s</xliff:g> a las <xliff:g id="TIME">%3$s</xliff:g>. Los informes de errores pueden incluir información personal sobre tu dispositivo o registrada por apps, como nombres de usuario, datos de ubicación, identificadores del dispositivo y datos de red. Solo debes compartir los informes de errores con personas y apps de confianza. ¿Permitir que <xliff:g id="APP_NAME_1">%4$s</xliff:g> suba un informe de errores?"</string> <string name="incident_report_error_dialog_text" msgid="4189647113387092272">"Se produjo un error al procesar el informe de errores para <xliff:g id="APP_NAME">%1$s</xliff:g>. Por lo tanto, no es posible compartir los datos detallados de depuración. Lamentamos la interrupción."</string> <string name="incident_report_dialog_allow_label" msgid="2970242967721155239">"Permitir"</string> - <string name="incident_report_dialog_deny_label" msgid="3535314290677579383">"Denegar"</string> + <string name="incident_report_dialog_deny_label" msgid="3535314290677579383">"Rechazar"</string> <string name="adjust_user_sensitive_title" msgid="4196724451314280527">"Configuración avanzada"</string> <string name="menu_adjust_user_sensitive" msgid="6497923610654425780">"Configuración avanzada"</string> <string name="adjust_user_sensitive_globally_title" msgid="8649190949066029174">"Mostrar uso de las apps del sistema"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"Esta app quiere grabar audio todo el tiempo, incluso cuando no la uses. "<annotation id="link">"Permite el acceso en Configuración."</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"¿Quieres permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> acceda a tu actividad física?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"¿Permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> acceda a la actividad física en tu <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"¿Permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tome fotos y grabe videos?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"¿Quieres permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tome fotos y grabe videos?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"¿Permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tome fotos y grabe videos en tu <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"La app solo podrá tomar fotos y grabar videos cuando esté en uso"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"¿Permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tome fotos y grabe videos?"</string> @@ -614,7 +621,7 @@ <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Mostrar acceso a portapapeles"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Muestra un mensaje cuando las apps accedan a texto, imágenes y otro contenido que hayas copiado"</string> <string name="show_password_title" msgid="2877269286984684659">"Mostrar contraseñas"</string> - <string name="show_password_summary" msgid="1110166488865981610">"Mostrar caracteres brevemente mientras escribes"</string> + <string name="show_password_summary" msgid="1110166488865981610">"Muestra los caracteres brevemente mientras escribes"</string> <string name="permission_rationale_message_location" msgid="2153841534298068414">"Esta app indicó que podría compartir datos de ubicación con terceros"</string> <string name="permission_rationale_location_title" msgid="2404797182678793506">"Uso compartido de datos y ubicación"</string> <string name="permission_rationale_data_sharing_source_title" msgid="6874604543125814316">"De dónde proviene la información de uso compartido de datos"</string> @@ -644,8 +651,24 @@ <string name="shares_location_with_third_parties" msgid="2278051743742057767">"Tus datos de ubicación ahora se comparten con terceros"</string> <string name="shares_location_with_third_parties_for_advertising" msgid="1918588064014480513">"Tus datos de ubicación ahora se comparten con terceros para publicidad o marketing"</string> <string name="updated_in_last_days" msgid="8371811947153042322">"{count,plural, =0{Se actualizó en el último día}=1{Se actualizó en el último día}many{Se actualizó en los últimos # de días}other{Se actualizó en los últimos # días}}"</string> - <string name="no_updates_at_this_time" msgid="9031085635689982935">"No hay novedades por el momento"</string> + <string name="no_updates_at_this_time" msgid="9031085635689982935">"No hay actualizaciones por el momento"</string> <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Actualizaciones del uso compartido de datos"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Algunas apps cambiaron la forma en que podrían compartir tus datos de ubicación"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Configuración"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Último acceso: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Último acceso: ayer a la(s) <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Último acceso: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> a la(s) <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Tu contraseña de un solo uso es 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Parámetro restringido"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Por seguridad, este parámetro de configuración no está disponible actualmente."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"A la app se le negó el acceso a <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"La app solicitó acceso a un permiso sensible, lo que puede poner en riesgo tu información financiera y personal.<xliff:g id="ID_1"><br><br></xliff:g>Es posible que la app no funcione como corresponde sin este permiso restringido. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Descubre cómo permitir el acceso</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"A la app se le negó el acceso para usarse como <xliff:g id="ROLE_NAME">%1$s</xliff:g> de forma predeterminada"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"La app solicitó acceso a permisos sensibles, lo que puede poner en riesgo tu información financiera y personal.<xliff:g id="ID_1"><br><br></xliff:g>Es posible que la app no funcione como corresponde sin estos permisos restringidos. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Descubre cómo permitir el acceso</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"A la app se le negó el acceso"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"El acceso a este permiso puede poner en riesgo tu información financiera y personal.<xliff:g id="ID_1"><br><br></xliff:g>Es posible que la app no funcione como corresponde sin este permiso restringido. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Descubre cómo permitir el acceso</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Más información"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Aceptar"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Se rechazó la solicitud de permiso"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Esta app solicita permisos adicionales, pero estos no se pueden otorgar durante una sesión de transmisión. Primero, otorga el permiso en el teléfono."</string> </resources> diff --git a/PermissionController/res/values-es-v34/strings.xml b/PermissionController/res/values-es-v34/strings.xml index 8253d9b47..3f3c3c15e 100644 --- a/PermissionController/res/values-es-v34/strings.xml +++ b/PermissionController/res/values-es-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gestiona el acceso de las aplicaciones a tus datos de salud"</string> <string name="location_settings" msgid="8863940440881290182">"Acceso a la ubicación"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Para aplicaciones y servicios. Aunque este ajuste esté desactivado, se pueden compartir datos del micrófono si llamas a un número de emergencia."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Para aplicaciones y servicios"</string> </resources> diff --git a/PermissionController/res/values-es-watch/strings.xml b/PermissionController/res/values-es-watch/strings.xml index db42f6961..92bbdd057 100644 --- a/PermissionController/res/values-es-watch/strings.xml +++ b/PermissionController/res/values-es-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"No cambiar"</string> <string name="generic_yes" msgid="2489207724988649846">"Sí"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancelar"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Todo el tiempo"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Mientras se usa la app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Todo el tiempo"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Mientras se usa la app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Todo el tiempo"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Mientras se usa la app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Todo el tiempo"</string> </resources> diff --git a/PermissionController/res/values-es/strings.xml b/PermissionController/res/values-es/strings.xml index 54f7751c2..31b66a1a8 100644 --- a/PermissionController/res/values-es/strings.xml +++ b/PermissionController/res/values-es/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Todos los permisos"</string> <string name="other_permissions" msgid="2901186127193849594">"Otras funciones de la aplicación"</string> <string name="permission_request_title" msgid="8790310151025020126">"Solicitud de permiso"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Las acciones de instalar y desinstalar no pueden realizarse en Wear"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Elige los permisos de acceso que quieres conceder a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> se ha actualizado. Elige los permisos de acceso que quieres conceder a esta aplicación."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancelar"</string> @@ -195,10 +193,11 @@ <string name="app_permission_button_deny" msgid="6016454069832050300">"No permitir"</string> <string name="precise_image_description" msgid="6349638632303619872">"Ubicación precisa"</string> <string name="approximate_image_description" msgid="938803699637069884">"Ubicación aproximada"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Usar ubicación precisa"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Usar ubic. precisa"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Cuando la ubicación precisa está desactivada, las aplicaciones pueden consultar tu ubicación aproximada"</string> <string name="app_permission_title" msgid="2090897901051370711">"Permiso de <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Acceso a <xliff:g id="PERM">%1$s</xliff:g> para esta aplicación"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Acceso de <xliff:g id="PERM">%1$s</xliff:g> a esta aplicación en <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ver todos los permisos de <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Ver todas las aplicaciones con este permiso"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostrar el uso del micrófono del Asistente"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Quitar permisos si la aplicación no se usa"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Quitar permisos y liberar espacio"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausar actividad de la aplicación si no se usa"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gestionar la aplicación si no se usa"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Quita permisos, elimina archivos temporales y detiene las notificaciones"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Quita permisos, elimina archivos temporales, detiene las notificaciones y archiva la aplicación"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para proteger tus datos, se quitarán los permisos de esta aplicación si no la usas durante unos meses."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para proteger tus datos, si la aplicación no se ha utilizado durante unos meses, se quitarán los siguientes permisos: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para proteger tus datos, se han quitado los permisos de las aplicaciones que llevas unos meses sin usar."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Pueden gestionar todos los archivos"</string> <string name="ask_header" msgid="2633816846459944376">"Preguntar siempre"</string> <string name="denied_header" msgid="903209608358177654">"No permitidas"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> en <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Ver más aplicaciones que pueden acceder a todos los archivos"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 día}many{# días}other{# días}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hora}many{# horas}other{# horas}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplicación de notas"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplicaciones que te permiten tomar notas en tu dispositivo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notas"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"App de cartera predeterminada"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplicación de cartera"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Las aplicaciones de cartera pueden almacenar tus tarjetas de crédito y de fidelización, tus llaves del coche y otros elementos para ayudarte con los distintos tipos de transacciones."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"¿Establecer <xliff:g id="APP_NAME">%1$s</xliff:g> como aplicación de cartera predeterminada?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"No se necesita ningún permiso"</string> <string name="request_role_current_default" msgid="738722892438247184">"Predeterminada"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"No volver a preguntar"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Establecer como predeterminado"</string> @@ -627,7 +634,7 @@ <string name="permission_rationale_location_settings_title" msgid="7204145004850190953">"Tus datos de ubicación"</string> <string name="permission_rationale_permission_settings_message" msgid="631286040979660267">"Cambia el acceso de esta aplicación en la "<annotation id="link">"configuración de privacidad"</annotation></string> <string name="permission_rationale_purpose_app_functionality" msgid="8397736681065841405">"Funcionalidad de la aplicación"</string> - <string name="permission_rationale_purpose_analytics" msgid="2070800501189620712">"Analítica"</string> + <string name="permission_rationale_purpose_analytics" msgid="2070800501189620712">"Estadísticas"</string> <string name="permission_rationale_purpose_developer_communications" msgid="6453047018892062374">"Comunicaciones del desarrollador"</string> <string name="permission_rationale_purpose_advertising" msgid="7156966429245180236">"Publicidad o marketing"</string> <string name="permission_rationale_purpose_fraud_prevention_security" msgid="4262104770357031902">"Prevención de fraudes, seguridad y cumplimiento"</string> @@ -644,8 +651,24 @@ <string name="shares_location_with_third_parties" msgid="2278051743742057767">"Tus datos de ubicación ahora se comparten con terceros"</string> <string name="shares_location_with_third_parties_for_advertising" msgid="1918588064014480513">"Tus datos de ubicación ahora se comparten con terceros para fines de publicidad o marketing"</string> <string name="updated_in_last_days" msgid="8371811947153042322">"{count,plural, =0{Se ha actualizado en el último día}=1{Se ha actualizado en el último día}many{Se ha actualizado en los últimos # días}other{Se ha actualizado en los últimos # días}}"</string> - <string name="no_updates_at_this_time" msgid="9031085635689982935">"No hay novedades por el momento"</string> + <string name="no_updates_at_this_time" msgid="9031085635689982935">"No hay cambios por el momento"</string> <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Cambios en cómo se comparten los datos"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Algunas aplicaciones han cambiado cómo pueden compartir tus datos de ubicación"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Ajustes"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Último acceso: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Último acceso: ayer, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Último acceso: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Tu contraseña de un solo uso es 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ajuste restringido"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Por seguridad, este ajuste no está disponible actualmente."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Se ha denegado el acceso a <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> a la aplicación"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"La aplicación ha solicitado acceso a un permiso sensible que puede poner en riesgo tu información personal y financiera.<xliff:g id="ID_1"><br><br></xliff:g>Es posible que la aplicación no funcione correctamente sin este permiso restringido. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Consulta cómo permitir el acceso</a>."</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Se ha denegado el acceso para ser <xliff:g id="ROLE_NAME">%1$s</xliff:g> de forma predeterminada a la aplicación"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"La aplicación ha solicitado acceso a permisos sensibles que pueden poner en riesgo tu información personal y financiera.<xliff:g id="ID_1"><br><br></xliff:g>Es posible que la aplicación no funcione correctamente sin estos permisos restringidos. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Consulta cómo permitir el acceso</a>."</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Se ha denegado el acceso a la aplicación"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"El acceso a este permiso puede poner en riesgo tu información personal y financiera.<xliff:g id="ID_1"><br><br></xliff:g>Es posible que la aplicación no funcione correctamente sin este permiso restringido. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Consulta cómo permitir el acceso</a>."</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Más información"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Aceptar"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Solicitud de permiso rechazada"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Esta aplicación está solicitando permisos adicionales, pero no se pueden dar durante una sesión de streaming. Da primero el permiso en tu teléfono."</string> </resources> diff --git a/PermissionController/res/values-et-v34/strings.xml b/PermissionController/res/values-et-v34/strings.xml index 4476aecdd..2db42fd0e 100644 --- a/PermissionController/res/values-et-v34/strings.xml +++ b/PermissionController/res/values-et-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Saate hallata rakenduse juurdepääsu terviseandmetele"</string> <string name="location_settings" msgid="8863940440881290182">"Juurdepääs asukohale"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Rakenduste ja teenuste jaoks. Isegi kui see seade on välja lülitatud, võidakse mikrofoni andmeid siiski jagada hädaabinumbrile helistades."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Rakenduste ja teenuste jaoks"</string> </resources> diff --git a/PermissionController/res/values-et-watch/strings.xml b/PermissionController/res/values-et-watch/strings.xml index b96aab80f..9813469ea 100644 --- a/PermissionController/res/values-et-watch/strings.xml +++ b/PermissionController/res/values-et-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Ei saa muuta"</string> <string name="generic_yes" msgid="2489207724988649846">"Jah"</string> <string name="generic_cancel" msgid="2631708607129269698">"Tühista"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Kogu aeg"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Rakenduse kasutamise ajal"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Kogu aeg"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Rakenduse kasutamise ajal"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Kogu aeg"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Rakenduse kasutamise ajal"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Kogu aeg"</string> </resources> diff --git a/PermissionController/res/values-et/strings.xml b/PermissionController/res/values-et/strings.xml index f17cbd1f8..797c5bf72 100644 --- a/PermissionController/res/values-et/strings.xml +++ b/PermissionController/res/values-et/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Kõik load"</string> <string name="other_permissions" msgid="2901186127193849594">"Rakenduse muud funktsioonid"</string> <string name="permission_request_title" msgid="8790310151025020126">"Loa taotlus"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear ei toeta installimist/desinstallimist."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Valige, millele lubate rakendusel <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> juurde pääseda"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Rakendust <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> värskendati. Valige, millele lubate sellel rakendusel juurde pääseda."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Tühista"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kui täpne asukoht on välja lülitatud, pääsevad rakendused juurde teie ligikaudsele asukohale"</string> <string name="app_permission_title" msgid="2090897901051370711">"Funktsiooni <xliff:g id="PERM">%1$s</xliff:g> luba"</string> <string name="app_permission_header" msgid="2951363137032603806">"Rakenduse juurdepääs funktsioonile <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> juurdepääs sellele rakendusele seadmes <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Kuva rakenduse <xliff:g id="APP">%1$s</xliff:g> kõik load"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Kuva kõik selle loaga rakendused"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Kuva assistendi mikrofoni kasutamine"</string> <string name="unused_apps_category_title" msgid="2988455616845243901">"Kasutamata rakenduse seaded"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"Eemalda load, kui rakendust ei kasutata"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Eemalda load ja vabasta ruumi"</string> - <string name="unused_apps_label_v2" msgid="7058776770056517980">"Tegevusetuna rakenduse tegevuste peatamine"</string> + <string name="unused_apps_label_v2" msgid="7058776770056517980">"Kasutamata rakenduse tegevuste peatamine"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Halda kasutamata rakendusi"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Eemaldatakse load, kustutatakse ajutised failid ja peatatakse märguanded"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Eemalda load, kustuta ajutised failid, peata märguanded ja arhiivi rakendus"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Teie andmete kaitsmiseks eemaldatakse selle rakenduse load, kui seda mõne kuu jooksul ei kasutata."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Teie andmete kaitsmiseks eemaldatakse selle rakenduse järgmised load, kui rakendust mõne kuu jooksul ei kasutata: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Teie andmete kaitsmiseks eemaldati load rakendustelt, mida te ei ole mõne kuu jooksul kasutanud."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Luba kõikide failide haldamiseks"</string> <string name="ask_header" msgid="2633816846459944376">"Küsi iga kord"</string> <string name="denied_header" msgid="903209608358177654">"Pole lubatud"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> seadmes <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Kuva rohkem rakendusi, mis kõigile failidele juurde pääsevad"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 päev}other{# päeva}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# tund}other{# tundi}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Märkmerakendus"</string> <string name="role_notes_description" msgid="8496852798616883551">"Rakendused, mis võimaldavad teie seadmes märkmeid teha"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"märkmed"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Vaikerahakotirakendus"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Rahakotirakendus"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Rahakotirakendused võivad salvestada teie krediit- ja kliendikaarte, autovõtmeid ning muid asju, et eri tehinguvormide puhul aidata."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Kas määrata <xliff:g id="APP_NAME">%1$s</xliff:g> vaikimisi teie rahakotirakenduseks?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Lube ei ole vaja"</string> <string name="request_role_current_default" msgid="738722892438247184">"Praegune vaikeseade"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ära enam küsi"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Määra vaikeseadeks"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Andmete jagamise värskendused"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Mõni rakendus on muutnud teie asukohaandmete jagamise viisi"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Seaded"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Juurde pääsetud <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Juurde pääsetud eile <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Juurde pääsetud <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Teie ühekordne parool on 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Piiratud seade"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Teie turvalisuse huvides pole see seade praegu saadaval."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Rakendusele ei antud luba <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Rakendus taotles tundlikku luba, mis võib teie isikuandmed ja finantsteabe ohtu seada.<xliff:g id="ID_1"><br><br></xliff:g>Võimalik, et rakendus ei tööta ilma selle piiratud loata korralikult. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>> Teave juurdepääsu andmise kohta</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Rakendusele ei antud luba olla vaikimisi <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Rakendus taotles tundlikke lubasid, mis võivad teie isikuandmed ja finantsteabe ohtu seada.<xliff:g id="ID_1"><br><br></xliff:g>Võimalik, et rakendus ei tööta ilma nende piiratud lubadeta korralikult. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>> Teave loa andmise kohta</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Rakendusele ei antud luba"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Selle loa andmine võib teie isikuandmed ja finantsteabe ohtu seada.<xliff:g id="ID_1"><br><br></xliff:g>Võimalik, et rakendus ei tööta ilma selle piiratud loata korralikult. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>> Teave loa andmise kohta</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Lisateave"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Loataotlus peideti"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"See rakendus taotleb lisalube, kuid lube ei saa voogesituse seansis anda. Kõigepealt andke luba oma telefonile."</string> </resources> diff --git a/PermissionController/res/values-eu-v34/strings.xml b/PermissionController/res/values-eu-v34/strings.xml index 5b1882738..d1921fe84 100644 --- a/PermissionController/res/values-eu-v34/strings.xml +++ b/PermissionController/res/values-eu-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Kudeatu aplikazioak osasunari buruzko datuak erabiltzeko duen baimena"</string> <string name="location_settings" msgid="8863940440881290182">"Kokapena erabiltzeko baimena"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Aplikazio eta zerbitzuetarako. Ezarpena desaktibatuta badago ere, baliteke mikrofonoaren bidez lortutako datuak partekatzea larrialdietarako zenbaki batera deitzean."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Aplikazio eta zerbitzuetarako"</string> </resources> diff --git a/PermissionController/res/values-eu-watch/strings.xml b/PermissionController/res/values-eu-watch/strings.xml index 840f6faef..0617758e9 100644 --- a/PermissionController/res/values-eu-watch/strings.xml +++ b/PermissionController/res/values-eu-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Ezin da aldatu"</string> <string name="generic_yes" msgid="2489207724988649846">"Bai"</string> <string name="generic_cancel" msgid="2631708607129269698">"Utzi"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Beti"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Aplikazioa erabili bitartean"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Beti"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Aplikazioa erabili bitartean"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Beti"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Aplikazioa erabili bitartean"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Beti"</string> </resources> diff --git a/PermissionController/res/values-eu/strings.xml b/PermissionController/res/values-eu/strings.xml index a84c1f9ca..fb635888f 100644 --- a/PermissionController/res/values-eu/strings.xml +++ b/PermissionController/res/values-eu/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Baimen guztiak"</string> <string name="other_permissions" msgid="2901186127193849594">"Aplikazioaren beste gaitasun batzuk"</string> <string name="permission_request_title" msgid="8790310151025020126">"Baimen-eskaera"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Instalatzeko eta desinstalatzeko ekintzak ezin dira gauzatu Wear gailuetan."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Aukeratu zer atzi dezakeen <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioak"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Eguneratu egin da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Aukeratu aplikazioak zer atzi dezakeen."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Utzi"</string> @@ -152,7 +150,7 @@ <string name="permission_usage_last_n_minutes" msgid="7817864229878281983">"{count,plural, =1{Azken # minutuan}other{Azken # minutuetan}}"</string> <string name="no_permission_usages" msgid="9119517454177289331">"Ez da eskatu baimenik"</string> <string name="permission_usage_list_title_any_time" msgid="8718257027381592407">"Orain arteko azken sarbidea"</string> - <string name="permission_usage_list_title_last_7_days" msgid="9048542342670890615">"Azken zazpi egunetako azken sarbidea"</string> + <string name="permission_usage_list_title_last_7_days" msgid="9048542342670890615">"Azken 7 egunetako azken sarbidea"</string> <string name="permission_usage_list_title_last_day" msgid="8730907824567238461">"Azken 24 orduetan erabilitakoak"</string> <string name="permission_usage_list_title_last_hour" msgid="6624161487623223716">"Azken ordubeteko azken sarbidea"</string> <string name="permission_usage_list_title_last_15_minutes" msgid="8615062016024296833">"Azken 15 minutuetako azken sarbidea"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kokapen zehatza desaktibatuta dagoenean, aplikazioek gutxi gorabeherako kokapena atzi dezakete"</string> <string name="app_permission_title" msgid="2090897901051370711">"\"<xliff:g id="PERM">%1$s</xliff:g>\" baimena"</string> <string name="app_permission_header" msgid="2951363137032603806">"Aplikazio honek \"<xliff:g id="PERM">%1$s</xliff:g>\" erabiltzeko duen baimena"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> erabiltzeko baimena aplikazio honetarako <xliff:g id="DEVICE_NAME">%2$s</xliff:g> gailuan"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ikusi <xliff:g id="APP">%1$s</xliff:g> aplikazioaren baimen guztiak"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Ikusi baimen hau duten aplikazio guztiak"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Erakutsi laguntzaileak mikrofonoa erabiltzeko duen baimena"</string> - <string name="unused_apps_category_title" msgid="2988455616845243901">"Erabili gabeko aplikazio-ezarpenak"</string> + <string name="unused_apps_category_title" msgid="2988455616845243901">"Erabili gabeko aplikazioen ezarpenak"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"Kendu baimenak aplikazioa erabiltzen ez bada"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Kendu baimenak eta egin tokia"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausatu aplikazioko jarduerak, erabiltzen ez bada"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Kudeatu aplikazioa erabiltzen ez bada"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Kendu baimenak, ezabatu aldi baterako fitxategiak eta geldiarazi jakinarazpenak"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Kendu baimenak, ezabatu aldi baterako fitxategiak, geldiarazi jakinarazpenak eta artxibatu aplikazioa"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Zure datuak babeste aldera, aplikazio honen baimenak kendu egingo dira aplikazioa ez baduzu erabiltzen zenbait hilabetez."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Zure datuak babeste aldera, kendu egingo dira honako baimen hauek zenbait hilabetez aplikazioa erabiltzen ez baduzu: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Zure datuak babeste aldera, kendu egin dira zenbait hilabetez erabili ez dituzun aplikazioen baimenak."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Fitxategi guztiak kudeatzeko baimena dutenak"</string> <string name="ask_header" msgid="2633816846459944376">"Galdetu beti"</string> <string name="denied_header" msgid="903209608358177654">"Baimendu gabekoak"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Ikusi fitxategi guztiak atzi ditzaketen aplikazio gehiago"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 egun}other{# egun}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ordu}other{# ordu}}"</string> @@ -354,7 +356,7 @@ <string name="role_assistant_description" msgid="6622458130459922952">"Ikusten ari zaren pantailako informazioaren araberako laguntza eskain diezazukete laguntza-aplikazioek. Zenbait aplikaziok abiarazlea eta ahots bidezko zerbitzuak onartzen dituzte laguntza integratua eskaintzeko."</string> <string name="role_browser_label" msgid="2877796144554070207">"Arakatzaile lehenetsia"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"Arakatzaile-aplikazioa"</string> - <string name="role_browser_description" msgid="3465253637499842671">"Interneterako sarbidea ematen dizuten eta sakatzen dituzun estekak bistaratzen dituzten aplikazioak"</string> + <string name="role_browser_description" msgid="3465253637499842671">"Interneteko sarbidea ematen dizuten eta sakatzen dituzun estekak bistaratzen dituzten aplikazioak"</string> <string name="role_browser_request_title" msgid="2895200507835937192">"<xliff:g id="APP_NAME">%1$s</xliff:g> ezarri nahi duzu arakatzaile-aplikazio lehenetsi gisa?"</string> <string name="role_browser_request_description" msgid="5888803407905985941">"Ez du behar baimenik"</string> <string name="role_dialer_label" msgid="1100224146343237968">"Telefono lehenetsia"</string> @@ -377,7 +379,7 @@ <string name="role_emergency_search_keywords" msgid="1920007722599213358">"ice"</string> <string name="role_home_label" msgid="3871847846649769412">"Hasierako aplikazio lehenetsia"</string> <string name="role_home_short_label" msgid="8544733747952272337">"Hasierako aplikazioa"</string> - <string name="role_home_description" msgid="7997371519626556675">"Android-eko gailuko hasierako pantailak ordezten dituzten aplikazioak (\"abiarazle\" ere deitzen zaie). Gailuko eduki eta eginbideetarako sarbidea ematen dute."</string> + <string name="role_home_description" msgid="7997371519626556675">"Android-eko gailuko orri nagusiak ordezten dituzten aplikazioak (\"abiarazle\" ere deitzen zaie). Gailuko eduki eta eginbideetarako sarbidea ematen dute."</string> <string name="role_home_request_title" msgid="738136983453341081">"<xliff:g id="APP_NAME">%1$s</xliff:g> ezarri nahi duzu hasierako aplikazio lehenetsi gisa?"</string> <string name="role_home_request_description" msgid="2658833966716057673">"Ez du behar baimenik"</string> <string name="role_home_search_keywords" msgid="3830755001192666285">"abiarazlea"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Oharren aplikazioa"</string> <string name="role_notes_description" msgid="8496852798616883551">"Gailuan oharrak idazteko aukera ematen dizuten aplikazioak"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"oharrak"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Diru-zorro lehenetsia"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Diru-zorroaren aplikazioa"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Diru-zorroaren aplikazioetan zure saldoa eta fideltasun-txartelak, autoko giltzak nahiz bestelako gauzak gorde ditzakezu, errazagoa izan dadin askotariko transakzioak egitea."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> diru-zorro lehenetsi gisa ezarri nahi duzu?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Ez du behar baimenik"</string> <string name="request_role_current_default" msgid="738722892438247184">"Aplikazio lehenetsia"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ez galdetu berriro"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Ezarri lehenetsi gisa"</string> @@ -445,7 +452,7 @@ <string name="incident_report_notification_text" msgid="3376480583513587923">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak arazketa-informazioa kargatu nahi du."</string> <string name="incident_report_dialog_title" msgid="669104389325204095">"Arazketa-datuak partekatu nahi dituzu?"</string> <string name="incident_report_dialog_intro" msgid="5897733669850951832">"Arazo bat hauteman du sistemak."</string> - <string name="incident_report_dialog_text" msgid="5675553296891757523">"<xliff:g id="DATE">%2$s</xliff:g> (<xliff:g id="TIME">%3$s</xliff:g>) datan sortutako akatsen txostena kargatzeko baimena eskatzen ari da <xliff:g id="APP_NAME_0">%1$s</xliff:g>. Akatsen txostenek zure gailuari buruzkoa den edo aplikazioek erregistratu duten informazio pertsonala dute; adibidez, erabiltzaile-izenak, kokapenari buruzko datuak, gailuaren identifikatzaileak eta sareari buruzko informazioa. Informazio hori izateko fidagarriak iruditzen zaizkizun pertsona eta aplikazioekin soilik partekatu beharko zenituzke akatsen txostenak. <xliff:g id="APP_NAME_1">%4$s</xliff:g> aplikazioari akatsen txostena kargatzeko baimena eman nahi diozu?"</string> + <string name="incident_report_dialog_text" msgid="5675553296891757523">"<xliff:g id="DATE">%2$s</xliff:g> (<xliff:g id="TIME">%3$s</xliff:g>) datan sortutako akatsen txostena kargatzeko baimena eskatzen ari da <xliff:g id="APP_NAME_0">%1$s</xliff:g>. Akatsen txostenek zure gailuari buruzkoa den edo aplikazioek erregistratu duten informazio pertsonala dute; adibidez, erabiltzaile-izenak, kokapenari buruzko datuak, gailu-identifikatzaileak eta sareari buruzko informazioa. Informazio hori izateko fidagarriak iruditzen zaizkizun pertsona eta aplikazioekin soilik partekatu beharko zenituzke akatsen txostenak. <xliff:g id="APP_NAME_1">%4$s</xliff:g> aplikazioari akatsen txostena kargatzeko baimena eman nahi diozu?"</string> <string name="incident_report_error_dialog_text" msgid="4189647113387092272">"Errore bat gertatu da <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren akatsen txostena prozesatzean; beraz, ezin izan dira partekatu arazketa-datu xehatuak. Barkatu eragozpenak."</string> <string name="incident_report_dialog_allow_label" msgid="2970242967721155239">"Eman baimena"</string> <string name="incident_report_dialog_deny_label" msgid="3535314290677579383">"Ukatu"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Datuak partekatzeko aukeraren berritasunak"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Kokapen-datuak partekatzeko modua aldatu dute aplikazio batzuek"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Ezarpenak"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Atzitze-data: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Atzo atzitu zen (<xliff:g id="TIME_DATE">%1$s</xliff:g>)"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Atzitze-data: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> (<xliff:g id="TIME_DATE_1">%2$s</xliff:g>)"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Zure erabilera bakarreko pasahitza 132435 da"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Murriztapenak ditu ezarpenak"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Zure segurtasuna bermatzeko, ezarpena ez dago erabilgarri une honetan."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikazioari <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> erabiltzeko baimena ukatu zaio"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Kontuzko informazioa erabiltzeko baimen bat eskatu du aplikazioak, eta agian horrek arriskuan jarriko ditu zure informazio pertsonala eta finantzei buruzko informazioa.<xliff:g id="ID_1"><br><br></xliff:g>Baliteke aplikazioak behar bezala ez funtzionatzea baimen murriztu hori gabe. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Lortu baimena emateko argibideak</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikazioari <xliff:g id="ROLE_NAME">%1$s</xliff:g> lehenetsia izateko baimena ukatu zaio"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Kontuzko informazioa erabiltzeko baimen batzuk eskatu ditu aplikazioak, eta agian horrek arriskuan jarriko ditu zure informazio pertsonala eta finantzei buruzko informazioa.<xliff:g id="ID_1"><br><br></xliff:g>Baliteke aplikazioak behar bezala ez funtzionatzea baimen murriztu horiek gabe. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Lortu baimena emateko argibideak</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikazioari baimena ukatu zaio"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Baimen hau emanez gero, agian arriskuan jarriko dira zure informazio pertsonala eta finantzei buruzko informazioa.<xliff:g id="ID_1"><br><br></xliff:g>Baliteke aplikazioak behar bezala ez funtzionatzea baimen murriztu hori gabe. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Lortu baimena emateko argibideak</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Lortu informazio gehiago"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Ados"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Blokeatu da baimen-eskaera"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Baimen gehigarriak eskatzen ari da aplikazioa, baina ezin da eman baimenik igorpen-saioetan. Lehenik eta behin, eman baimena telefonoan."</string> </resources> diff --git a/PermissionController/res/values-fa-v34/strings.xml b/PermissionController/res/values-fa-v34/strings.xml index de8036122..386c748dc 100644 --- a/PermissionController/res/values-fa-v34/strings.xml +++ b/PermissionController/res/values-fa-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"مدیریت دسترسی برنامه به دادههای سلامت"</string> <string name="location_settings" msgid="8863940440881290182">"دسترسی به مکان"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"برای برنامهها و سرویسها. اگر این تنظیم خاموش باشد، ممکن است وقتی با شماره تلفنی اضطراری تماس میگیرید دادههای میکروفون همچنان همرسانی شود"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"برای برنامهها و سرویسها"</string> </resources> diff --git a/PermissionController/res/values-fa-watch/strings.xml b/PermissionController/res/values-fa-watch/strings.xml index 17b225913..b602b38f3 100644 --- a/PermissionController/res/values-fa-watch/strings.xml +++ b/PermissionController/res/values-fa-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"امکان تغییر نیست"</string> <string name="generic_yes" msgid="2489207724988649846">"بله"</string> <string name="generic_cancel" msgid="2631708607129269698">"لغو"</string> + <string name="permission_access_always" msgid="2107115233573823032">"همیشه"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"درحین استفاده از برنامه"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"همیشه"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"درحین استفاده از برنامه"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"همیشه"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"درحین استفاده از برنامه"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"همیشه"</string> </resources> diff --git a/PermissionController/res/values-fa/strings.xml b/PermissionController/res/values-fa/strings.xml index 671694e0d..fd655ed71 100644 --- a/PermissionController/res/values-fa/strings.xml +++ b/PermissionController/res/values-fa/strings.xml @@ -50,12 +50,12 @@ <string name="permission_revoked_all" msgid="3397649017727222283">"همه مجوزها غیرفعال است"</string> <string name="permission_revoked_none" msgid="9213345075484381180">"هیچ موردی غیرفعال نیست"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"اجازه دادن"</string> - <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"همیشه مجاز است"</string> + <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"همیشه مجاز"</string> <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"هنگام استفاده از برنامه"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"تغییر به مکان دقیق"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"حفظ مکان تقریبی"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"فقط این بار"</string> - <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"همیشه مجاز است"</string> + <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"همیشه مجاز"</string> <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"اجازه دادن برای مدیریت همه فایلها"</string> <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"اجازه دادن برای دسترسی به فایلهای رسانه"</string> <string name="app_permissions_breadcrumb" msgid="5136969550489411650">"برنامهها"</string> @@ -109,15 +109,13 @@ <!-- no translation found for background_access_chooser_dialog_choices:0 (1351721623256561996) --> <!-- no translation found for background_access_chooser_dialog_choices:1 (9127301153688725448) --> <!-- no translation found for background_access_chooser_dialog_choices:2 (4305536986042401191) --> - <string name="permission_access_always" msgid="1474641821883823446">"همیشه مجاز است"</string> - <string name="permission_access_only_foreground" msgid="7801170728159326195">"فقط هنگام استفاده از برنامه مجاز است"</string> + <string name="permission_access_always" msgid="1474641821883823446">"همیشه مجاز"</string> + <string name="permission_access_only_foreground" msgid="7801170728159326195">"مجاز فقط هنگام استفاده از برنامه"</string> <string name="permission_access_never" msgid="4647014230217936900">"اجازه ندادن"</string> <string name="loading" msgid="4789365003890741082">"درحال بارگیری…"</string> <string name="all_permissions" msgid="6911125611996872522">"همه اجازهها"</string> <string name="other_permissions" msgid="2901186127193849594">"سایر قابلیتهای برنامه"</string> <string name="permission_request_title" msgid="8790310151025020126">"درخواست اجازه"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"کنشهای نصب/حذف نصب در Wear پشتیبانی نمیشود."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"انتخاب کنید <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> اجازه دارد به چه چیزی دسترسی پیدا کند"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بهروزرسانی شده است. انتخاب کنید این برنامه اجازه دارد به چه چیزی دسترسی پیدا کند."</string> <string name="review_button_cancel" msgid="2191147944056548886">"لغو"</string> @@ -188,8 +186,8 @@ <string name="app_permission_button_allow" msgid="5808039516494774647">"اجازه دادن"</string> <string name="app_permission_button_allow_all_files" msgid="1792232272599018825">"اجازه دادن برای مدیریت همه فایلها"</string> <string name="app_permission_button_allow_media_only" msgid="2834282724426046154">"اجازه دادن فقط برای دسترسی به رسانهها"</string> - <string name="app_permission_button_allow_always" msgid="4573292371734011171">"همیشه مجاز است"</string> - <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"فقط هنگام استفاده از برنامه مجاز است"</string> + <string name="app_permission_button_allow_always" msgid="4573292371734011171">"همیشه مجاز"</string> + <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"مجاز فقط هنگام استفاده از برنامه"</string> <string name="app_permission_button_always_allow_all" msgid="4905699259378428855">"همه موارد همیشه مجازاند"</string> <string name="app_permission_button_ask" msgid="3342950658789427">"هربار پرسیده شود"</string> <string name="app_permission_button_deny" msgid="6016454069832050300">"اجازه ندادن"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"وقتی «مکان دقیق» خاموش باشد، برنامهها میتوانند به مکان تقریبیتان دسترسی داشته باشند"</string> <string name="app_permission_title" msgid="2090897901051370711">"اجازه <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"دسترسی <xliff:g id="PERM">%1$s</xliff:g> برای این برنامه"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"دسترسی <xliff:g id="PERM">%1$s</xliff:g> از این برنامه در <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"مشاهده همه اجازههای <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"دیدن همه برنامههایی که این مجوز را دارند"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"نمایش میزان استفاده «دستیار» از میکروفون"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"اگر از برنامه استفاده نمیشود، اجازهها برداشته شوند"</string> <string name="unused_apps_label" msgid="2595428768404901064">"برداشتن اجازهها و آزاد کردن فضا"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"مکث فعالیتها در برنامه درصورت عدماستفاده"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"مدیریت برنامه درصورت عدم استفاده"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"اجازهها برداشته میشود، فایلهای موقت حذف میشود، و اعلانها متوقف میشوند"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"برداشتن اجازهها، حذف فایلهای موقت، توقف اعلانها، و بایگانی کردن برنامه"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"برای محافظت از دادههایتان، اگر طی چند ماه گذشته از این برنامه استفاده نشده باشد، اجازههای آن برداشته خواهد شد."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"برای محافظت از دادههایتان، اگر طی چند ماه گذشته از این برنامه استفاده نشده باشد، اجازههای زیر برداشته خواهد شد: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"برای محافظت از دادههایتان، اجازهها از برنامههایی که طی چند ماه گذشته استفاده نشدهاند برداشته شده است."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"مجاز برای مدیریت همه فایلها"</string> <string name="ask_header" msgid="2633816846459944376">"هربار پرسیده شود"</string> <string name="denied_header" msgid="903209608358177654">"مجاز نبودن"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> در <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"دیدن برنامههای دیگری که به همه فایلها دسترسی دارند"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{یک روز}one{# روز}other{# روز}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ساعت}one{# ساعت}other{# ساعت}}"</string> @@ -403,15 +405,20 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"برنامه یادداشتها"</string> <string name="role_notes_description" msgid="8496852798616883551">"برنامههایی که به شما اجازه میدهند در دستگاهتان یادداشتبرداری کنید"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"یادداشت"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"برنامه کیف پول پیشفرض"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"برنامه کیف پول"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"برنامههای کیف پول میتواند با ذخیره کردن کارتهای اعتباری و وفاداری، کلید خودرو، و موارد دیگر در انجام انواع مختلف تراکنش به شما کمک کند."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> بهعنوان برنامه کیف پول پیشفرض تنظیم شود؟"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"اجازهای لازم نیست"</string> <string name="request_role_current_default" msgid="738722892438247184">"برنامه پیشفرض کنونی"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"دوباره سؤال نشود"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"تنظیم برای پیشفرض"</string> <string name="phone_call_uses_microphone" msgid="233569591461187177">"در <b>تماس تلفنی</b> از میکروفون استفاده میشود"</string> <string name="phone_call_uses_microphone_and_camera" msgid="6291898755681748189">"در <b>تماس تصویری</b> از دوربین و میکروفون استفاده میشود"</string> <string name="phone_call_uses_camera" msgid="2048417022147857418">"در <b>تماس تصویری</b> از دوربین استفاده میشود"</string> - <string name="system_uses_microphone" msgid="576672130318877143">"سرویس سیستم به میکروفون دسترسی دارد"</string> - <string name="system_uses_microphone_and_camera" msgid="5124478304275138804">"سرویس سیستم به دوربین و میکروفون دسترسی دارد"</string> - <string name="system_uses_camera" msgid="1911223105234441470">"سرویس سیستم به دوربین دسترسی دارد"</string> + <string name="system_uses_microphone" msgid="576672130318877143">"خدمات سیستم به میکروفون دسترسی دارد"</string> + <string name="system_uses_microphone_and_camera" msgid="5124478304275138804">"خدمات سیستم به دوربین و میکروفون دسترسی دارد"</string> + <string name="system_uses_camera" msgid="1911223105234441470">"خدمات سیستم به دوربین دسترسی دارد"</string> <string name="other_use" msgid="6564855051022776692">"استفادههای دیگر:"</string> <string name="ongoing_usage_dialog_ok" msgid="103556809118460072">"متوجه شدم"</string> <string name="ongoing_usage_dialog_title" msgid="683836493556628569">"استفاده اخیر از <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> @@ -553,12 +560,12 @@ <string name="safety_center_rescan_button" msgid="4517514567809409596">"اسکن کردن دستگاه"</string> <string name="safety_center_issue_card_dismiss_button" msgid="5113965506144222402">"رد کردن"</string> <string name="safety_center_issue_card_dismiss_confirmation_title" msgid="2734809473425036382">"این هشدار رد شود؟"</string> - <string name="safety_center_issue_card_dismiss_confirmation_message" msgid="3775418736671093563">"هرزمان خواستید تنظیمات امنیت و حریم خصوصی را مرور کنید تا محافظت بیشتری اضافه کنید"</string> + <string name="safety_center_issue_card_dismiss_confirmation_message" msgid="3775418736671093563">"هرزمان خواستید تنظیمات ایمنی و حریم خصوصی را مرور کنید تا محافظت بیشتری اضافه کنید"</string> <string name="safety_center_issue_card_confirm_dismiss_button" msgid="5884137843083634556">"رد شدن"</string> <string name="safety_center_issue_card_cancel_dismiss_button" msgid="2874578798877712346">"لغو"</string> <string name="safety_center_entries_category_title" msgid="34356964062813115">"تنظیمات"</string> <string name="safety_status_preference_title_and_summary_content_description" msgid="3511373256505058464">"وضعیت حریم خصوصی و امنیت. <xliff:g id="OVERALL_SAFETY_STATUS">%1$s</xliff:g>. <xliff:g id="SUMMARY_OF_DEVICE_STATUS">%2$s</xliff:g>"</string> - <string name="security_settings" msgid="3808106921175271317">"تنظیمات امنیتی"</string> + <string name="security_settings" msgid="3808106921175271317">"تنظیمات ایمنی"</string> <string name="sensor_permissions_qs" msgid="1022267900031317472">"اجازهها"</string> <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"امنیت و حریم خصوصی"</string> <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"بررسی وضعیت"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"بهروزرسانیهای همرسانی داده"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"برخیاز برنامهها روش همرسانی دادههای مکان شما را تغییر دادهاند"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"تنظیمات"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"تاریخ دسترسی: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"دسترسی در روز گذشته ساعت <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"دسترسی در <xliff:g id="TIME_DATE_0">%1$s</xliff:g> ساعت <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"گذرواژه یکبارمصرف شما 132435 است"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"تنظیم محدودشده"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"برای حفظ امنیت شما، درحالحاضر این تنظیم دردسترس نیست."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"درخواست برنامه برای دسترسی به <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> رد شد"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"این برنامه درخواست دسترسی به اجازهای حساس را داشته است که میتواند اطلاعات شخصی و مالیتان را درمعرض خطر قرار دهد.<xliff:g id="ID_1"><br><br></xliff:g>ممکن است برنامه بدون این اجازه محدودشده بهدرستی کار نکند. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>با نحوه اعطای دسترسی آشنا شوید</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"درخواست دسترسی برنامه برای تبدیل شدن به <xliff:g id="ROLE_NAME">%1$s</xliff:g> پیشفرض رد شد"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"این برنامه درخواست دسترسی به اجازههای حساسی را داشته است که میتواند اطلاعات شخصی و مالیتان را درمعرض خطر قرار دهد.<xliff:g id="ID_1"><br><br></xliff:g>ممکن است برنامه بدون این اجازههای محدودشده بهدرستی کار نکند. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>با نحوه اعطای دسترسی آشنا شوید</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"درخواست دسترسی برنامه رد شد"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"اعطای این اجازه میتواند اطلاعات شخصی و مالیتان را درمعرض خطر قرار دهد.<xliff:g id="ID_1"><br><br></xliff:g>ممکن است برنامه بدون این اجازه محدودشده بهدرستی کار نکند. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>با نحوه اعطای دسترسی آشنا شوید</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"بیشتر بدانید"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"بسیارخوب"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"درخواست اجازه رد شد"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"این برنامه درخواست اجازههای اضافی دارد، اما امکان دادن این اجازهها در جلسه جاریسازی وجود ندارد. ابتدا اجازه را در تلفنتان اعطا کنید."</string> </resources> diff --git a/PermissionController/res/values-fi-v34/strings.xml b/PermissionController/res/values-fi-v34/strings.xml index b2f95dc19..b00393067 100644 --- a/PermissionController/res/values-fi-v34/strings.xml +++ b/PermissionController/res/values-fi-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Päätä sovellusten pääsystä terveysdataan"</string> <string name="location_settings" msgid="8863940440881290182">"Pääsy sijaintiin"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Sovellukset ja palvelut. Vaikka asetus olisi poissa päältä, mikrofonidataa saatetaan silti jakaa, kun soitat hätänumeroon"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Sovellukset ja palvelut"</string> </resources> diff --git a/PermissionController/res/values-fi-watch/strings.xml b/PermissionController/res/values-fi-watch/strings.xml index 843f06a71..296eedf2b 100644 --- a/PermissionController/res/values-fi-watch/strings.xml +++ b/PermissionController/res/values-fi-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Ei muutettavissa"</string> <string name="generic_yes" msgid="2489207724988649846">"Kyllä"</string> <string name="generic_cancel" msgid="2631708607129269698">"Peru"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Aina"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Sovelluksen käytön aikana"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Aina"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Sovelluksen käytön aikana"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Aina"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Sovelluksen käytön aikana"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Aina"</string> </resources> diff --git a/PermissionController/res/values-fi/strings.xml b/PermissionController/res/values-fi/strings.xml index ee85d8df2..af206f851 100644 --- a/PermissionController/res/values-fi/strings.xml +++ b/PermissionController/res/values-fi/strings.xml @@ -73,7 +73,7 @@ <string name="days_ago" msgid="6650359081551335629">"{count,plural, =0{Tänään}=1{1 päivä sitten}other{# päivää sitten}}"</string> <string name="app_disable_dlg_positive" msgid="7418444149981904940">"Poista sovellus käytöstä"</string> <string name="app_disable_dlg_text" msgid="3126943217146120240">"Jos poistat sovelluksen käytöstä, Android ja muut sovellukset eivät välttämättä enää toimi oikein. Muista, ettet voi poistaa sovellusta, sillä se tuli laitteesi mukana. Poistamalla sovelluksen käytöstä suljet sen ja piilotat sen laitteella."</string> - <string name="app_permission_manager" msgid="3903811137630909550">"Lupien ylläpito"</string> + <string name="app_permission_manager" msgid="3903811137630909550">"Lupienhallinta"</string> <string name="never_ask_again" msgid="4728762438198560329">"Älä kysy enää"</string> <string name="no_permissions" msgid="3881676756371148563">"Ei lupia"</string> <string name="additional_permissions" msgid="5801285469338873430">"Lisäluvat"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Kaikki luvat"</string> <string name="other_permissions" msgid="2901186127193849594">"Muut sovellusluvat"</string> <string name="permission_request_title" msgid="8790310151025020126">"Lupapyyntö"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear ei tue asennus- ja poistotoimintoja."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Valitse, mitä käyttöoikeuksia sovellukselle <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> myönnetään."</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> on päivitetty. Valitse, mitä käyttöoikeuksia tälle sovellukselle myönnetään."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Peru"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kun tarkka sijainti ei ole päällä, sovellukset voivat nähdä likimääräisen sijaintisi"</string> <string name="app_permission_title" msgid="2090897901051370711">"Lupa (<xliff:g id="PERM">%1$s</xliff:g>)"</string> <string name="app_permission_header" msgid="2951363137032603806">"Sovellus pyytää pääsyä näihin: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Tällä sovelluksella on pääsy (<xliff:g id="PERM">%1$s</xliff:g>) laitteella <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Näytä kaikki luvat, jotka <xliff:g id="APP">%1$s</xliff:g> on saanut"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Näytä kaikki sovellukset, joilla on tämä lupa"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Näytä Assistantin mikrofonin käyttö"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Poista luvat, jos sovellusta ei käytetä"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Poista lupia ja vapauta tilaa"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Keskeytä sovellustoim. jos ei käytössä"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Hallinnoi sovellusta, jos käyttämätön"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Poista käyttämättömät luvat ja väliaikaiset tiedostot ja pysäytä ilmoitukset"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Poista käyttämättömät luvat ja väliaikaiset tiedostot, pysäytä ilmoitukset ja arkistoi sovellus"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Datasi suojaamiseksi tämän sovelluksen luvat poistetaan, jos sovellusta ei käytetä muutamaan kuukauteen."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Jos sovellusta ei käytetä muutamaan kuukauteen, seuraavat luvat poistetaan datasi suojaamiseksi: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Datasi suojaamiseksi luvat on poistettu sovelluksilta, joita et ole käyttänyt muutamaan kuukauteen."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Kaikkien tiedostojen ylläpito sallittu"</string> <string name="ask_header" msgid="2633816846459944376">"Kysy aina"</string> <string name="denied_header" msgid="903209608358177654">"Ei sallittu"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Muut sovellukset, joilla on pääsy kaikkiin tiedostoihin"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 päivä}other{# päivää}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# tunti}other{# tuntia}}"</string> @@ -401,8 +403,13 @@ <string name="role_companion_device_computer_description" msgid="416099879217066377">"Tämä palvelu jakaa kuvat, median ja ilmoitukset puhelimeltasi muille laitteille."</string> <string name="role_notes_label" msgid="7451627001058089536">"Oletusmuistiinpanosovellus"</string> <string name="role_notes_short_label" msgid="8796604147546125285">"Muistiinpanosovellus"</string> - <string name="role_notes_description" msgid="8496852798616883551">"Sovellukset, joilla voit ottaa muistiinpanoja laitteellasi"</string> + <string name="role_notes_description" msgid="8496852798616883551">"Sovellukset, joilla voit tehdä muistiinpanoja laitteellasi"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"muistiinpanot"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Oletuslompakkosovellus"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Lompakkosovellus"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Lompakkosovelluksista on apua erilaisissa tapahtumissa, koska ne voivat tallentaa esimerkiksi credit- ja kanta-asiakaskortit ja autonavaimet"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Valitaanko <xliff:g id="APP_NAME">%1$s</xliff:g> oletuslompakkosovelluksesi?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Lupia ei tarvita"</string> <string name="request_role_current_default" msgid="738722892438247184">"Nykyinen oletus"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Älä kysy uudelleen"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Aseta oletukseksi"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Datan jaon päivitykset"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Jotkin sovellukset ovat muuttaneet tapaa, jolla ne voivat jakaa sijaintitietoja"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Asetukset"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Avattu <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Avattu eilen klo <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Avattu <xliff:g id="TIME_DATE_0">%1$s</xliff:g> klo <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Kertakäyttöinen salasanasi on 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Rajoitettu asetus"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Asetus ei ole tällä hetkellä käytettävissä turvallisuussyistä."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Sovellukselta on evätty pääsy: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Sovellus on pyytänyt pääsyä arkaluontoiseen lupaan, joka voi vaarantaa henkilökohtaisia tietojasi ja taloustietojasi.<xliff:g id="ID_1"><br><br></xliff:g>Sovellus ei välttämättä toimi oikein ilman tätä rajoitettua lupaa. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Lue, miten voit sallia pääsyn</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Sovellus ei saa olla oletuksena <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Sovellus on pyytänyt pääsyä arkaluontoisiin lupiin, jotka voivat vaarantaa henkilökohtaisia tietojasi ja taloustietojasi.<xliff:g id="ID_1"><br><br></xliff:g>Sovellus ei välttämättä toimi oikein ilman näitä rajoitettuja lupia. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Lue, miten voit sallia pääsyn</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Sovellukselta on evätty pääsy"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Tämä lupa voi vaarantaa henkilökohtaisia tietojasi ja taloustietojasi.<xliff:g id="ID_1"><br><br></xliff:g>Sovellus ei välttämättä toimi oikein ilman tätä rajoitettua lupaa. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Lue, miten voit sallia pääsyn</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Lue lisää"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Lupapyyntö estetty"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Sovellus pyytää lisälupia, mutta lupia ei voi myöntää striimatessa. Myönnä lupa ensin puhelimella."</string> </resources> diff --git a/PermissionController/res/values-fr-rCA-v34/strings.xml b/PermissionController/res/values-fr-rCA-v34/strings.xml index 347b04cc8..4b18ba2f6 100644 --- a/PermissionController/res/values-fr-rCA-v34/strings.xml +++ b/PermissionController/res/values-fr-rCA-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gérez l\'accès des applications aux données relatives à la santé"</string> <string name="location_settings" msgid="8863940440881290182">"Accès à la position"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Pour les applications et les services. Si ce paramètre est désactivé, il est possible que les données du microphone soient partagées lorsque vous appelez un numéro d\'urgence"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Pour les applications et les services"</string> </resources> diff --git a/PermissionController/res/values-fr-rCA-watch/strings.xml b/PermissionController/res/values-fr-rCA-watch/strings.xml index 8e92df18e..4d588d0c9 100644 --- a/PermissionController/res/values-fr-rCA-watch/strings.xml +++ b/PermissionController/res/values-fr-rCA-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Inchangeable"</string> <string name="generic_yes" msgid="2489207724988649846">"Oui"</string> <string name="generic_cancel" msgid="2631708607129269698">"Annuler"</string> + <string name="permission_access_always" msgid="2107115233573823032">"En tout temps"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Quand l\'appli est utilisée"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"En tout temps"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Quand l\'appli est utilisée"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"En tout temps"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Quand l\'appli est utilisée"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"En tout temps"</string> </resources> diff --git a/PermissionController/res/values-fr-rCA/strings.xml b/PermissionController/res/values-fr-rCA/strings.xml index 50d896bcb..237496eae 100644 --- a/PermissionController/res/values-fr-rCA/strings.xml +++ b/PermissionController/res/values-fr-rCA/strings.xml @@ -110,14 +110,12 @@ <!-- no translation found for background_access_chooser_dialog_choices:1 (9127301153688725448) --> <!-- no translation found for background_access_chooser_dialog_choices:2 (4305536986042401191) --> <string name="permission_access_always" msgid="1474641821883823446">"Toujours autoriser"</string> - <string name="permission_access_only_foreground" msgid="7801170728159326195">"Autoriser si l\'application est utilisée"</string> + <string name="permission_access_only_foreground" msgid="7801170728159326195">"Autoriser uniquement lorsque l\'application est utilisée"</string> <string name="permission_access_never" msgid="4647014230217936900">"Ne pas autoriser"</string> <string name="loading" msgid="4789365003890741082">"Chargement en cours…"</string> <string name="all_permissions" msgid="6911125611996872522">"Toutes les autorisations"</string> <string name="other_permissions" msgid="2901186127193849594">"Autres autorisations de l\'application"</string> <string name="permission_request_title" msgid="8790310151025020126">"Demande d\'autorisation"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Les actions d\'installation et de désinstallation ne sont pas prises en charge par Android Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Définissez les autorisations d\'accès de l\'application « <xliff:g id="APP_NAME">%1$s</xliff:g> »"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"L\'application « <xliff:g id="APP_NAME">%1$s</xliff:g> » a été mise à jour. Définissez ses autorisations d\'accès."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Annuler"</string> @@ -189,7 +187,7 @@ <string name="app_permission_button_allow_all_files" msgid="1792232272599018825">"Autoriser à gérer tous les fichiers"</string> <string name="app_permission_button_allow_media_only" msgid="2834282724426046154">"Autoriser à accéder aux éléments multimédias seulement"</string> <string name="app_permission_button_allow_always" msgid="4573292371734011171">"Toujours autoriser"</string> - <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"Autoriser uniquement lorsque l\'appli est en cours d\'utilisation"</string> + <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"Autoriser uniquement lorsque l\'application est utilisée"</string> <string name="app_permission_button_always_allow_all" msgid="4905699259378428855">"Toujours tout autoriser"</string> <string name="app_permission_button_ask" msgid="3342950658789427">"Toujours demander"</string> <string name="app_permission_button_deny" msgid="6016454069832050300">"Ne pas autoriser"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Si la position exacte est désactivée, les applications ont accès à votre position approximative"</string> <string name="app_permission_title" msgid="2090897901051370711">"Autorisation : <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Accès pour cette application : <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Accès <xliff:g id="PERM">%1$s</xliff:g> pour cette application sur <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Afficher toutes les autorisations pour <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Afficher toutes les applications qui possèdent cette autorisation"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Afficher l\'usage du microphone de l\'assistant"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Retirer les autorisations si l\'application est inutilisée"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Retirer autorisations et libérer espace"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Suspendre l\'activité appli si inutilisée"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gérer l\'application si inutilisée"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Retirer les autorisations, supprimer les fichiers temporaires et arrêter les notifications"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Retirer les autorisations, supprimer les fichiers temporaires, arrêter les notifications et archiver l\'application"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Afin de protéger vos données, les autorisations pour cette application seront retirées si elle n\'est pas utilisée pendant quelques mois."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Afin de protéger vos données, si l\'application n\'est pas utilisée pendant quelques mois, les autorisations suivantes seront supprimées : <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Afin de protéger vos données, les autorisations ont été supprimées pour les applications que vous n\'avez pas utilisées depuis quelques mois."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Autorisées à gérer tous les fichiers"</string> <string name="ask_header" msgid="2633816846459944376">"Toujours demander"</string> <string name="denied_header" msgid="903209608358177654">"Non autorisées"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> sur <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Afficher d\'autres applis pouvant accéder à tous les fichiers"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 jour}one{# jour}many{# jours}other{# jours}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# heure}one{# heure}many{# d\'heures}other{# heures}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Application de prise de notes"</string> <string name="role_notes_description" msgid="8496852798616883551">"Applications qui vous permettent de prendre des notes sur votre appareil"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"remarques"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Appli portefeuille par défaut"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Application de portefeuille"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Les applications de portefeuille peuvent stocker vos cartes de crédit et de fidélité, vos clés de voiture et d\'autres données pour faciliter différentes modalités de transaction."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Définir <xliff:g id="APP_NAME">%1$s</xliff:g> comme application de portefeuille par défaut?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Aucune autorisation nécessaire"</string> <string name="request_role_current_default" msgid="738722892438247184">"Application par défaut actuelle"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ne plus me demander"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Définir par défaut"</string> @@ -464,7 +471,7 @@ <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à accéder à la position de votre « <xliff:g id="DEVICE_NAME">%2$s</xliff:g> »?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"L\'application aura uniquement accès à la position lorsque vous l\'utilisez"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à accéder à la position de cet appareil?"</string> - <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à accéder à la position de votre « <xliff:g id="DEVICE_NAME">%2$s</xliff:g> »?"</string> + <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Autoriser <xliff:g id="APP_NAME">%1$s</xliff:g> à accéder à la position de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g>?"</string> <string name="permgroupbackgroundrequestdetail_location" msgid="8021219324989662957">"Cette appli pourrait demander à accéder à votre position en tout temps, même si vous ne l\'utilisez pas. Accordez cette autorisation dans les "<annotation id="link">"paramètres"</annotation>"."</string> <string name="permgroupupgraderequest_location" msgid="8328408946822691636">"Modifier l\'accès à la position pour « <xliff:g id="APP_NAME">%1$s</xliff:g> »?"</string> <string name="permgroupupgraderequest_device_aware_location" msgid="4528266408056426513">"Modifier l\'accès à la position pour « <xliff:g id="APP_NAME">%1$s</xliff:g> » sur votre « <xliff:g id="DEVICE">%2$s</xliff:g> »?"</string> @@ -648,4 +655,26 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Mises à jour des pratiques de partage des données"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Certaines applis ont modifié comment elles peuvent partager vos données de localisation"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Paramètres"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Dernier accès : <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Accès hier (<xliff:g id="TIME_DATE">%1$s</xliff:g>)"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Accès : <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Votre mot de passe à usage unique est le suivant : 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Paramètre restreint"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Pour protéger votre sécurité, ce paramètre n\'est pas accessible actuellement."</string> + <!-- no translation found for enhanced_confirmation_dialog_title_permission (2149144789394238266) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_permission (3150778951946468945) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_title_role (1737023798483772780) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_role (6369601947905234551) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_title_settings_default (1858092969721041576) --> + <skip /> + <!-- no translation found for enhanced_confirmation_dialog_desc_settings_default (6911632348359332981) --> + <skip /> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"En savoir plus"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Demande d\'autorisation supprimée"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Cette appli demande des autorisations supplémentaires, mais celles-ci ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez d\'abord l\'autorisation de votre téléphone."</string> </resources> diff --git a/PermissionController/res/values-fr-v34/strings.xml b/PermissionController/res/values-fr-v34/strings.xml index f7f584b75..bfd957bcb 100644 --- a/PermissionController/res/values-fr-v34/strings.xml +++ b/PermissionController/res/values-fr-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gérer l\'accès de l\'appli aux données de santé"</string> <string name="location_settings" msgid="8863940440881290182">"Accès à la position"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Pour les applis et services. Si ce paramètre est désactivé, il est possible que les données du micro soient quand même partagées quand vous appelez un numéro d\'urgence"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Pour les applis et services"</string> </resources> diff --git a/PermissionController/res/values-fr-watch/strings.xml b/PermissionController/res/values-fr-watch/strings.xml index c9df92552..2ef84f46c 100644 --- a/PermissionController/res/values-fr-watch/strings.xml +++ b/PermissionController/res/values-fr-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Non modifiable"</string> <string name="generic_yes" msgid="2489207724988649846">"Oui"</string> <string name="generic_cancel" msgid="2631708607129269698">"Annuler"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Tout le temps"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Quand l\'appli est utilisée"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Tout le temps"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Quand l\'appli est utilisée"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Tout le temps"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Lorsque vous utilisez l\'appli"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Tout le temps"</string> </resources> diff --git a/PermissionController/res/values-fr/strings.xml b/PermissionController/res/values-fr/strings.xml index 97c3461e5..dfcc73100 100644 --- a/PermissionController/res/values-fr/strings.xml +++ b/PermissionController/res/values-fr/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Toutes les autorisations"</string> <string name="other_permissions" msgid="2901186127193849594">"Autres fonctionnalités de l\'application"</string> <string name="permission_request_title" msgid="8790310151025020126">"Demande d\'autorisation"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Opérations d\'installation et de désinstallation impossibles sur Android Wear"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Sélectionner les éléments auxquels <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> peut accéder"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"L\'application <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> a été mise à jour. Sélectionnez les éléments auxquels elle peut accéder."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Annuler"</string> @@ -195,10 +193,11 @@ <string name="app_permission_button_deny" msgid="6016454069832050300">"Ne pas autoriser"</string> <string name="precise_image_description" msgid="6349638632303619872">"Position exacte"</string> <string name="approximate_image_description" msgid="938803699637069884">"Position approximative"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Utiliser la position exacte"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Position exacte"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Si la position exacte est désactivée, les applis ont accès à votre position approximative"</string> <string name="app_permission_title" msgid="2090897901051370711">"Autorisation d\'accès à \"<xliff:g id="PERM">%1$s</xliff:g>\""</string> <string name="app_permission_header" msgid="2951363137032603806">"Accès à \"<xliff:g id="PERM">%1$s</xliff:g>\" pour cette appli"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Accès à <xliff:g id="PERM">%1$s</xliff:g> pour cette application sur <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Voir toutes les autorisations pour <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Voir toutes les applis ayant cette autorisation"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Afficher l\'utilisation du micro par l\'Assistant"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Supprimer les autorisations si l\'application n\'est pas utilisée"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Supprimer autorisations et libérer espace"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Suspendre activité appli si inutilisée"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gérer l\'appli si inutilisée"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Retirer les autorisations, supprimer les fichiers temporaires et arrêter les notifications"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Retirer les autorisations, supprimer les fichiers temporaires, arrêter les notifications et archiver l\'appli"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Si cette application n\'est pas utilisée pendant plusieurs mois, ses autorisations seront supprimées afin de protéger vos données."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Pour protéger vos données, si l\'application n\'est pas utilisée pendant plusieurs mois, les autorisations suivantes seront supprimées : <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Afin de protéger vos données, les autorisations ont été supprimées pour les applications que vous n\'avez pas utilisées depuis plusieurs mois."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Autorisées à gérer tous les fichiers"</string> <string name="ask_header" msgid="2633816846459944376">"Toujours demander"</string> <string name="denied_header" msgid="903209608358177654">"Non autorisé"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> sur <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Voir plus d\'applis pouvant accéder à tous les fichiers"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 jour}one{# jour}many{# jours}other{# jours}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# heure}one{# heure}many{# heures}other{# heures}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Appli de notes"</string> <string name="role_notes_description" msgid="8496852798616883551">"Applis vous permettant de prendre des notes sur votre appareil"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Portefeuille numérique par défaut"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Appli portefeuille numérique"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Les applis de portefeuille numérique stockent vos cartes bancaires, cartes de fidélité, clés de voiture et bien d\'autres choses vous permettant d\'effectuer diverses transactions."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Définir <xliff:g id="APP_NAME">%1$s</xliff:g> comme appli de portefeuille numérique par défaut ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Aucune autorisation nécessaire"</string> <string name="request_role_current_default" msgid="738722892438247184">"Appli par défaut actuelle"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ne plus me demander"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Définir par défaut"</string> @@ -564,7 +571,7 @@ <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Vérifier l\'état"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Paramètres de confidentialité"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"Autres paramètres"</string> - <string name="camera_toggle_label_qs" msgid="3880261453066157285">"Accès à la caméra"</string> + <string name="camera_toggle_label_qs" msgid="3880261453066157285">"Accès à l\'appareil photo"</string> <string name="microphone_toggle_label_qs" msgid="8132912469813396552">"Accès au micro"</string> <string name="permissions_removed_qs" msgid="8957319130625294572">"Autorisation supprimée"</string> <string name="camera_usage_qs" msgid="4394233566086665994">"Voir l\'utilisation récente de l\'appareil photo"</string> @@ -606,7 +613,7 @@ <string name="safety_center_background_location_access_revoked" msgid="6972274943343442213">"Accès modifié"</string> <string name="safety_center_view_recent_location_access" msgid="3524391299490678243">"Voir l\'utilisation récente de la localisation"</string> <string name="privacy_controls_title" msgid="7605929972256835199">"Paramètres de confidentialité"</string> - <string name="camera_toggle_title" msgid="1251201397431837666">"Accès à la caméra"</string> + <string name="camera_toggle_title" msgid="1251201397431837666">"Accès à l\'appareil photo"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"Accès au micro"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Pour les applis et services"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Pour les applis et services. Si ce paramètre est désactivé, il est possible que les données du micro soient quand même partagées quand vous appelez un numéro d\'urgence."</string> @@ -620,17 +627,17 @@ <string name="permission_rationale_data_sharing_source_title" msgid="6874604543125814316">"Origine des informations sur le partage des données"</string> <string name="permission_rationale_data_sharing_device_manufacturer_message" msgid="7569261218145653185">"Le développeur a fourni des infos au fabricant de cet appareil concernant la manière dont cette appli partage les données. Le développeur peut mettre à jour ces infos au fil du temps."</string> <string name="permission_rationale_data_sharing_source_message" msgid="8330794595417986883">"Le développeur a fourni des infos sur "<annotation id="link"><annotation id="install_source" example="App Store">"%1$s"</annotation></annotation>" concernant la manière dont cette appli partage les données. Le développeur peut mettre à jour ces infos au fil du temps."</string> - <string name="permission_rationale_location_purpose_title" msgid="5115877143670012618">"L\'appli peut partager données de localisation pour :"</string> + <string name="permission_rationale_location_purpose_title" msgid="5115877143670012618">"L\'appli peut partager des données de localis. pour :"</string> <string name="permission_rationale_permission_data_sharing_varies_title" msgid="9103718980919908316">"Partage des données variable"</string> <string name="permission_rationale_data_sharing_varies_message" msgid="4224469559084489222">"La gestion des données peut varier selon la version de l\'appli, l\'utilisation que vous en faites, votre région et votre âge. "<annotation id="link">"En savoir plus sur le partage des données"</annotation></string> <string name="permission_rationale_data_sharing_varies_message_without_link" msgid="4912763761399025094">"La gestion des données peut varier selon la version de l\'appli, l\'utilisation que vous en faites, votre région et votre âge."</string> <string name="permission_rationale_location_settings_title" msgid="7204145004850190953">"Vos données de localisation"</string> <string name="permission_rationale_permission_settings_message" msgid="631286040979660267">"Modifiez l\'accès de cette appli dans les "<annotation id="link">"paramètres de confidentialité"</annotation></string> - <string name="permission_rationale_purpose_app_functionality" msgid="8397736681065841405">"Fonctionnement de l\'appli"</string> - <string name="permission_rationale_purpose_analytics" msgid="2070800501189620712">"Données analytiques"</string> + <string name="permission_rationale_purpose_app_functionality" msgid="8397736681065841405">"le fonctionnement de l\'appli ;"</string> + <string name="permission_rationale_purpose_analytics" msgid="2070800501189620712">"les données analytiques ;"</string> <string name="permission_rationale_purpose_developer_communications" msgid="6453047018892062374">"Communications du développeur"</string> - <string name="permission_rationale_purpose_advertising" msgid="7156966429245180236">"Publicité ou marketing"</string> - <string name="permission_rationale_purpose_fraud_prevention_security" msgid="4262104770357031902">"Prévention des fraudes, sécurité et conformité"</string> + <string name="permission_rationale_purpose_advertising" msgid="7156966429245180236">"la publicité ou marketing ;"</string> + <string name="permission_rationale_purpose_fraud_prevention_security" msgid="4262104770357031902">"la prévention des fraudes, la sécurité et la conformité."</string> <string name="permission_rationale_purpose_personalization" msgid="1589973273682238708">"Personnalisation"</string> <string name="permission_rationale_purpose_account_management" msgid="2985772421946688879">"Gestion du compte"</string> <string name="app_permission_rationale_message" msgid="8511466916077100713">"Sécurité des données"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Modifications du partage des données"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Certaines applis ont modifié la façon dont elles peuvent partager vos données de localisation"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Paramètres"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Dernière consultation : <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Dernière consultation : hier, à <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Dernière consultation : <xliff:g id="TIME_DATE_0">%1$s</xliff:g><xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Votre mot de passe à usage unique est le suivant : 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Paramètre restreint"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Pour votre sécurité, ce paramètre est actuellement indisponible."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"L\'appli s\'est vu refuser l\'accès à <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Cette appli a demandé l\'accès à une autorisation sensible susceptible d\'exposer vos informations financières et personnelles à un risque.<xliff:g id="ID_1"><br><br></xliff:g>Si elle ne dispose pas d\'un accès à cette autorisation restreinte, l\'appli peut ne pas fonctionner correctement. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Découvrez comment autoriser l\'accès</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"L\'appli s\'est vu refuser l\'accès au statut de <xliff:g id="ROLE_NAME">%1$s</xliff:g> par défaut"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Cette appli a demandé l\'accès à des autorisations sensibles susceptibles d\'exposer vos informations financières et personnelles à un risque.<xliff:g id="ID_1"><br><br></xliff:g>Si elle ne dispose pas d\'un accès à ces autorisations restreintes, l\'appli peut ne pas fonctionner correctement. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Découvrez comment autoriser l\'accès</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"L\'appli s\'est vu refuser l\'accès"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"L\'accès à cette autorisation peut exposer vos informations financières et personnelles à un risque.<xliff:g id="ID_1"><br><br></xliff:g>Si elle ne dispose pas d\'un accès à cette autorisation restreinte, l\'appli peut ne pas fonctionner correctement. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Découvrez comment autoriser l\'accès</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"En savoir plus"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Demande d\'autorisation supprimée"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Cette appli demande des autorisations supplémentaires, mais il est impossible d\'accorder des autorisations lors d\'une session de streaming. Accordez tout d\'abord l\'autorisation sur votre téléphone."</string> </resources> diff --git a/PermissionController/res/values-gl-v34/strings.xml b/PermissionController/res/values-gl-v34/strings.xml index cabf7a43a..745a9a615 100644 --- a/PermissionController/res/values-gl-v34/strings.xml +++ b/PermissionController/res/values-gl-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Xestiona o acceso das aplicacións aos datos de saúde"</string> <string name="location_settings" msgid="8863940440881290182">"Acceso á localización"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Para aplicacións e servizos. Aínda que esta opción de configuración se atope desactivada, poderán compartirse datos do micrófono se chamas a un número de emerxencias"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Para aplicacións e servizos"</string> </resources> diff --git a/PermissionController/res/values-gl-watch/strings.xml b/PermissionController/res/values-gl-watch/strings.xml index ddb8916bb..060385455 100644 --- a/PermissionController/res/values-gl-watch/strings.xml +++ b/PermissionController/res/values-gl-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Cambio imposible"</string> <string name="generic_yes" msgid="2489207724988649846">"Si"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancelar"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Todo o tempo"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Coa aplicación en uso"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Todo o tempo"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Coa aplicación en uso"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Todo o tempo"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Coa aplicación en uso"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Todo o tempo"</string> </resources> diff --git a/PermissionController/res/values-gl/strings.xml b/PermissionController/res/values-gl/strings.xml index 5c5a61baf..3bf31f833 100644 --- a/PermissionController/res/values-gl/strings.xml +++ b/PermissionController/res/values-gl/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Todos os permisos"</string> <string name="other_permissions" msgid="2901186127193849594">"Outras funcionalidades da aplicación"</string> <string name="permission_request_title" msgid="8790310151025020126">"Solicitude de permiso"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"As accións de instalar e desinstalar non son compatibles con Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Seleccionar os permisos de acceso que queres dar á aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Actualizouse a aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Selecciona os permisos de acceso que lle queres dar."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancelar"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Cando a localización precisa está desactivada, as aplicacións poden acceder á túa localización aproximada"</string> <string name="app_permission_title" msgid="2090897901051370711">"Permiso de <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Permiso de acceso desta aplicación a: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Esta aplicación ten o seguinte permiso de acceso en <xliff:g id="DEVICE_NAME">%2$s</xliff:g>: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ver todos os permisos de <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Ver todas as aplicacións que teñen este permiso"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostrar uso do micrófono do Asistente"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Quitar permisos se non se usa a aplicación"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Quitar permisos e liberar espazo"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pór en pausa actividade de apps sen uso"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Xestionar aplicación se non se usa"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Quita permisos, elimina ficheiros temporais e detén as notificacións"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Quita permisos, elimina os ficheiros temporais, detén as notificacións e arquiva a aplicación"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para protexer os teus datos, quitaranse os permisos desta aplicación se pasas varios meses sen utilizala."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para protexer os teus datos, se a aplicación leva varios meses sen usarse, quitaranse os seguintes permisos: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para protexer os teus datos, quitáronse os permisos das aplicacións que levas varios meses sen usar."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Permiso para xestionar todos os ficheiros"</string> <string name="ask_header" msgid="2633816846459944376">"Preguntar sempre"</string> <string name="denied_header" msgid="903209608358177654">"Permiso non concedido"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> en <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Ver máis aplicacións con acceso a todos os ficheiros"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 día}other{# días}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hora}other{# horas}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplicación de notas"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplicacións que che permiten tomar notas no dispositivo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notas"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"App de carteira predeterminada"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplicación de carteira"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"As aplicacións de carteira poden almacenar as túas tarxetas de crédito e de fidelidade, as chaves do coche e outros obxectos para axudar en distintos tipos de transaccións."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Queres establecer <xliff:g id="APP_NAME">%1$s</xliff:g> como aplicación de carteira predeterminada?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Non se necesita ningún permiso"</string> <string name="request_role_current_default" msgid="738722892438247184">"App predeterminada actual"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Non preguntar de novo"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"App predeterminada"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Actualizacións de uso compartido de datos"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Algunhas aplicacións cambiaron a forma en que poden compartir os teus datos de localización"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Configuración"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Último acceso: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Último acceso: onte, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Último acceso: <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"O teu contrasinal dun só uso é 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Opción de configuración restrinxida"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Pola túa seguranza, esta opción de configuración non está dispoñible nestes momentos."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Denegóuselle á aplicación o acceso ao permiso: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"A aplicación solicitou acceso a un permiso confidencial que pode poñer en perigo a túa información persoal e financeira.<xliff:g id="ID_1"><br><br></xliff:g>É posible que a aplicación non funcione correctamente sen este permiso restrinxido. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Máis información sobre como permitir o acceso</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Denegóuselle á aplicación o acceso para actuar como <xliff:g id="ROLE_NAME">%1$s</xliff:g> de forma predeterminada"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"A aplicación solicitou acceso a permisos confidenciais que poden poñer en perigo a túa información persoal e financeira.<xliff:g id="ID_1"><br><br></xliff:g>É posible que a aplicación non funcione correctamente sen estes permisos restrinxidos. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Máis información sobre como permitir o acceso</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Denegóuselle á aplicación o acceso"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"O acceso a este permiso pode poñer en perigo a túa información persoal e financeira.<xliff:g id="ID_1"><br><br></xliff:g>É posible que a aplicación non funcione correctamente sen este permiso restrinxido. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Máis información sobre como permitir o acceso</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Máis información"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Aceptar"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Eliminouse a solicitude de permiso"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Esta aplicación solicita permisos adicionais, pero non se poden conceder nunha sesión de reprodución en tempo real. Primeiro tes que dar o permiso no teu teléfono."</string> </resources> diff --git a/PermissionController/res/values-gu-v34/strings.xml b/PermissionController/res/values-gu-v34/strings.xml index ba8a5deb0..cce1bac6a 100644 --- a/PermissionController/res/values-gu-v34/strings.xml +++ b/PermissionController/res/values-gu-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ઍપનો આરોગ્ય સંબંધિત ડેટાનો ઍક્સેસ મેનેજ કરો"</string> <string name="location_settings" msgid="8863940440881290182">"લોકેશન ઍક્સેસ"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ઍપ અને સેવાઓ માટે. આ સેટિંગ બંધ હોવા છતાં પણ, જ્યારે તમે ઇમર્જન્સી નંબર પર કૉલ કરો ત્યારે હજુ પણ માઇક્રોફોનનો ડેટા શેર કરવામાં આવી શકે"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ઍપ અને સેવાઓ માટે"</string> </resources> diff --git a/PermissionController/res/values-gu-watch/strings.xml b/PermissionController/res/values-gu-watch/strings.xml index 66f9cd41b..12db58045 100644 --- a/PermissionController/res/values-gu-watch/strings.xml +++ b/PermissionController/res/values-gu-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"બદલી શકતાં નથી"</string> <string name="generic_yes" msgid="2489207724988649846">"હા"</string> <string name="generic_cancel" msgid="2631708607129269698">"રદ કરો"</string> + <string name="permission_access_always" msgid="2107115233573823032">"હંમેશાં"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ઍપનો ઉપયોગ કરતા હો ત્યારે"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"હંમેશાં"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ઍપનો ઉપયોગ કરતા હો ત્યારે"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"હંમેશાં"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ઍપનો ઉપયોગ કરતા હો ત્યારે"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"હંમેશાં"</string> </resources> diff --git a/PermissionController/res/values-gu/strings.xml b/PermissionController/res/values-gu/strings.xml index bd5988260..c77bdf264 100644 --- a/PermissionController/res/values-gu/strings.xml +++ b/PermissionController/res/values-gu/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"બધી પરવાનગીઓ"</string> <string name="other_permissions" msgid="2901186127193849594">"અન્ય ઍપ સુવિધાઓ"</string> <string name="permission_request_title" msgid="8790310151025020126">"પરવાનગીની વિનંતી"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear પર ઇન્સ્ટૉલ/અનઇન્સ્ટૉલ ક્રિયાઓ સમર્થિત નથી."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને શેના ઍક્સેસ માટેની મંજૂરી આપવી તે પસંદ કરો"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> અપડેટ કરવામાં આવી છે. આ ઍપને શેના ઍક્સેસ માટેની મંજૂરી આપવી તે પસંદ કરો."</string> <string name="review_button_cancel" msgid="2191147944056548886">"રદ કરો"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"જ્યારે ચોક્કસ લોકેશન બંધ હોય, ત્યારે ઍપ તમારા અંદાજિત લોકેશનને ઍક્સેસ કરી શકે છે"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>ની પરવાનગી"</string> <string name="app_permission_header" msgid="2951363137032603806">"આ ઍપ માટે <xliff:g id="PERM">%1$s</xliff:g>નો ઍક્સેસ"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> પર આ ઍપ માટે <xliff:g id="PERM">%1$s</xliff:g>નો ઍક્સેસ"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g>ની બધી પરવાનગીઓ જુઓ"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"આ પરવાનગી સાથે બધી ઍપ જુઓ"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"આસિસ્ટંટ દ્વારા વપરાયેલો માઇક્રોફોનની પરવાનગીનો ડેટા બતાવો"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ઍપ ઉપયોગમાં ન હોવા પર પરવાનગીઓ કાઢી નાખો"</string> <string name="unused_apps_label" msgid="2595428768404901064">"પરવાનગીઓ કાઢી નાખો અને જગ્યા ખાલી કરો"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"જો ઉપયોગ કરતા ન હો, તો ઍપ પ્રવૃત્તિ થોભાવો"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"જો ઍપ વાપરતા ન હો, તો તેને મેનેજ કરો"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"પરવાનગીઓ કાઢી નાખો, હંગામી ફાઇલો ડિલીટ કરો અને નોટિફિકેશન બંધ કરો"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"પરવાનગીઓ કાઢી નાખો, હંગામી ફાઇલો ડિલીટ કરો, નોટિફિકેશન બંધ કરો અને ઍપને આર્કાઇવ કરો"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"તમારા ડેટાની સુરક્ષા કરવા માટે, જો ઍપનો કેટલાક મહિનાથી ઉપયોગ કરવામાં આવ્યો ન હોય, તો આ ઍપની પરવાનગીઓ કાઢી નાખવામાં આવશે."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"તમારા ડેટાની સુરક્ષા કરવા માટે, જો ઍપનો કેટલાક મહિનાથી ઉપયોગ કરવામાં આવ્યો ન હોય, તો નીચેની પરવાનગીઓ કાઢી નાખવામાં આવશે: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"તમારા ડેટાની સુરક્ષા માટે, તમારા દ્વારા કેટલાક મહિનાથી ઉપયોગમાં ન લેવાયેલી ઍપની પરવાનગીઓ કાઢી નાખવામાં આવી છે."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"બધી ફાઇલો મેનેજ કરવાની મંજૂરી છે"</string> <string name="ask_header" msgid="2633816846459944376">"દર વખતે પૂછો"</string> <string name="denied_header" msgid="903209608358177654">"મંજૂરી નથી"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> પર <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"બધી ફાઇલોને ઍક્સેસ કરી શકે તેવી વધુ ઍપ જુઓ"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 દિવસ}one{# દિવસ}other{# દિવસ}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# કલાક}one{# કલાક}other{# કલાક}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"નોંધ માટેની ઍપ"</string> <string name="role_notes_description" msgid="8496852798616883551">"ઍપ કે જે તમને તમારા ડિવાઇસ પર નોંધ કરવાની મંજૂરી આપે છે"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"નોંધ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ડિફૉલ્ટ વૉલેટ ઍપ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet ઍપ"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"વૉલેટ સંબંધી ઍપ તમારા ક્રેડિટ અને લૉયલ્ટિ કાર્ડ, કાર કી તેમજ વિવિધ વ્યવહારોમાં સહાય કરી શકતી અન્ય બાબતો સ્ટોર કરી શકે છે."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"શું <xliff:g id="APP_NAME">%1$s</xliff:g>ને તમારી ડિફૉલ્ટ વૉલેટ ઍપ તરીકે સેટ કરીએ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"કોઈ પરવાનગી જરૂરી નથી"</string> <string name="request_role_current_default" msgid="738722892438247184">"હાલની ડિફૉલ્ટ"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ફરીથી પૂછશો નહીં"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ડિફૉલ્ટ તરીકે સેટ"</string> @@ -610,7 +617,7 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"માઇક્રોફોનનો ઍક્સેસ"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"ઍપ અને સેવાઓ માટે"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"ઍપ અને સેવાઓ માટે. આ સેટિંગ બંધ હોવા છતાં પણ, જ્યારે તમે ઇમર્જન્સી નંબર પર કૉલ કરો ત્યારે કદાચ માઇક્રોફોનનો ડેટા શેર કરવામાં આવી શકે."</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"સ્થાનનો ઍક્સેસ ધરાવતી ઍપ અને તેની સેવાઓ જુઓ"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"લોકેશનનો ઍક્સેસ ધરાવતી ઍપ અને તેની સેવાઓ જુઓ"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"ક્લિપબોર્ડનો ઍક્સેસ બતાવો"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"જ્યારે ઍપ તમે કૉપિ કરેલી ટેક્સ્ટ, છબીઓ કે અન્ય કન્ટેન્ટનો ઍક્સેસ કરે, ત્યારે મેસેજ બતાવો"</string> <string name="show_password_title" msgid="2877269286984684659">"પાસવર્ડ બતાવો"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ડેટા શેરિંગ સંબંધિત અપડેટ"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"કેટલીક ઍપ દ્વારા તમારા લોકેશન ડેટાને શેર કરવાની રીત બદલવામાં આવી હોઈ શકે છે"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"સેટિંગ"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"ઍક્સેસ કર્યાનો સમય <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"ઍક્સેસ કર્યાનો સમય ગઈકાલે <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"ઍક્સેસ કર્યાનો સમય <xliff:g id="TIME_DATE_0">%1$s</xliff:g>ના રોજ <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"તમારો એક-વખત વપરાશનો પાસવર્ડ 132435 છે"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"પ્રતિબંધિત સેટિંગ"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"તમારી સુરક્ષા માટે, આ સેટિંગ હાલમાં ઉપલબ્ધ નથી."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"ઍપને <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>નો ઍક્સેસ નકારવામાં આવ્યો"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"આ ઍપ દ્વારા કોઈ સંવેદનશીલ માહિતીની પરવાનગીના ઍક્સેસની વિનંતી કરવામાં આવી છે, જેને કારણે તમારી વ્યક્તિગત અને નાણાકીય માહિતી જોખમમાં આવી શકે છે.<xliff:g id="ID_1"><br><br></xliff:g>એ પણ શક્ય છે કે આ પ્રતિબંધિત પરવાનગી વિના ઍપ કદાચ યોગ્ય રીતે કામ ન પણ કરી શકે. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ઍક્સેસ મંજૂર કરવાની રીત જાણો</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ઍપને ડિફૉલ્ટ <xliff:g id="ROLE_NAME">%1$s</xliff:g> બનવાનો ઍક્સેસ નકારવામાં આવ્યો"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"આ ઍપ દ્વારા કોઈ સંવેદનશીલ માહિતીની પરવાનગીઓના ઍક્સેસની વિનંતી કરવામાં આવી છે, જેને કારણે તમારી વ્યક્તિગત અને નાણાકીય માહિતી જોખમમાં આવી શકે છે.<xliff:g id="ID_1"><br><br></xliff:g>એ પણ શક્ય છે કે આ પ્રતિબંધિત પરવાનગી વિના ઍપ કદાચ યોગ્ય રીતે કામ ન પણ કરી શકે. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ઍક્સેસ મંજૂર કરવાની રીત જાણો</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ઍપને ઍક્સેસ નકારવામાં આવ્યો"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"આ પરવાનગીના ઍક્સેસને કારણે તમારી વ્યક્તિગત અને નાણાકીય માહિતી જોખમમાં આવી શકે છે.<xliff:g id="ID_1"><br><br></xliff:g>એ પણ શક્ય છે કે આ પ્રતિબંધિત પરવાનગી વિના ઍપ કદાચ યોગ્ય રીતે કામ ન પણ કરી શકે. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ઍક્સેસ મંજૂર કરવાની રીત જાણો</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"વધુ જાણો"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ઓકે"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"પરવાનગીની વિનંતી નકારવામાં આવી"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"આ ઍપ વધારાની પરવાનગીઓની વિનંતી કરી રહી છે પણ સ્ટ્રીમિંગ સત્રમાં પરવાનગીઓને મંજૂરી આપી શકાતી નથી. પહેલા તમારા ફોન પર પરવાનગીની મંજૂરી આપો."</string> </resources> diff --git a/PermissionController/res/values-hi-v34/strings.xml b/PermissionController/res/values-hi-v34/strings.xml index 7b95fb793..a3d956d7c 100644 --- a/PermissionController/res/values-hi-v34/strings.xml +++ b/PermissionController/res/values-hi-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"स्वास्थ्य की जानकारी से जुड़े डेटा के लिए, ऐप्लिकेशन का ऐक्सेस मैनेज करें"</string> <string name="location_settings" msgid="8863940440881290182">"जगह की जानकारी का ऐक्सेस"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ऐप्लिकेशन और सेवाओं के लिए. इस सेटिंग के बंद होने पर भी, माइक्रोफ़ोन के डेटा को शेयर किया जा सकता है. ऐसा तब होता है, जब किसी आपातकालीन नंबर पर कॉल किया जाता है"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ऐप्लिकेशन और सेवाओं के लिए"</string> </resources> diff --git a/PermissionController/res/values-hi-watch/strings.xml b/PermissionController/res/values-hi-watch/strings.xml index d8ddc7878..12d4356d3 100644 --- a/PermissionController/res/values-hi-watch/strings.xml +++ b/PermissionController/res/values-hi-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"बदला नहीं जा सकता"</string> <string name="generic_yes" msgid="2489207724988649846">"हां"</string> <string name="generic_cancel" msgid="2631708607129269698">"रद्द करें"</string> + <string name="permission_access_always" msgid="2107115233573823032">"हर समय"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ऐप इस्तेमाल करते समय"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"हर समय"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ऐप इस्तेमाल करते समय"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"हर समय"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ऐप इस्तेमाल करते समय"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"हर समय"</string> </resources> diff --git a/PermissionController/res/values-hi/strings.xml b/PermissionController/res/values-hi/strings.xml index 04b9167aa..adb1b329b 100644 --- a/PermissionController/res/values-hi/strings.xml +++ b/PermissionController/res/values-hi/strings.xml @@ -50,7 +50,7 @@ <string name="permission_revoked_all" msgid="3397649017727222283">"सभी अनुमतियां बंद हैं"</string> <string name="permission_revoked_none" msgid="9213345075484381180">"कोई अनुमति बंद नहीं है"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"अनुमति दें"</string> - <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"हमेशा के लिए अनुमति दें"</string> + <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"हम समय अनुमति है"</string> <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"ऐप्लिकेशन इस्तेमाल करते समय"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"जगह की सटीक जानकारी पर सेट करें"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"जगह की अनुमानित जानकारी सेव करें"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"सभी अनुमतियां"</string> <string name="other_permissions" msgid="2901186127193849594">"ऐप्लिकेशन को ये अनुमतियां भी दी गई हैं"</string> <string name="permission_request_title" msgid="8790310151025020126">"अनुमति पाने का अनुरोध"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear पर ऐप्लिकेशन इंस्टॉल या अनइंस्टॉल नहीं किए जा सकते."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"चुनें कि <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को किन चीज़ों को ऐक्सेस करने की अनुमति दी जाए"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को अपडेट कर दिया गया है. चुनें कि इस ऐप्लिकेशन को किन चीज़ों को ऐक्सेस करने की अनुमति दी जाए."</string> <string name="review_button_cancel" msgid="2191147944056548886">"रद्द करें"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"जगह की सटीक जानकारी देने वाली सुविधा बंद होने पर, ऐप्लिकेशन आपकी अनुमानित जगह की जानकारी को ऐक्सेस कर सकते हैं"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> की अनुमति"</string> <string name="app_permission_header" msgid="2951363137032603806">"इस ऐप्लिकेशन के लिए, <xliff:g id="PERM">%1$s</xliff:g> ऐक्सेस करने की अनुमति चाहिए"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> पर इस ऐप्लिकेशन के लिए <xliff:g id="PERM">%1$s</xliff:g> का ऐक्सेस"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g> को मिली सभी अनुमतियां देखें"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"इस अनुमति वाले सभी ऐप्लिकेशन देखें"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"असिस्टेंट माइक्रोफ़ोन के इस्तेमाल से जुड़ा डेटा दिखाएं"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ऐप्लिकेशन का इस्तेमाल न होने पर अनुमतियां हटाएं"</string> <string name="unused_apps_label" msgid="2595428768404901064">"अनुमतियां हटाएं और जगह खाली करें"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"इस्तेमाल न होने पर ऐप गतिविधि रोकें"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"इस्तेमाल नहीं हुआ ऐप्लिकेशन मैनेज करें"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ऐप्लिकेशन की अनुमतियां हटाएं, डिवाइस में कुछ समय के लिए रहने वाली फ़ाइलें मिटाएं, और सूचनाएं रोकें"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ऐप्लिकेशन की अनुमतियां हटाएं, डिवाइस में कुछ समय के लिए रहने वाली फ़ाइलें मिटाएं, सूचनाएं रोकें, और ऐप्लिकेशन संग्रहित करें"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"अगर इस ऐप्लिकेशन का इस्तेमाल कुछ महीनों तक नहीं किया गया, तो इसे दी गई अनुमतियां हटा दी जाएंगी. ऐसा आपके डेटा को सुरक्षित रखने के लिए किया जाएगा."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"अगर ऐप्लिकेशन कुछ महीनों से इस्तेमाल नहीं हुआ है, तो आपके डेटा को सुरक्षित रखने के लिए ये अनुमतियां हटा दी जाएंगी: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"जिन ऐप्लिकेशन का इस्तेमाल कुछ महीनों से नहीं हुआ है उन्हें दी गई अनुमतियां हटा दी गई हैं. ऐसा आपके डेटा को सुरक्षित रखने के लिए किया गया है."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ये ऐप्लिकेशन सभी फ़ाइलों को मैनेज कर सकते हैं"</string> <string name="ask_header" msgid="2633816846459944376">"हर बार पूछें"</string> <string name="denied_header" msgid="903209608358177654">"अनुमति नहीं है"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> पर <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ऐसे और ऐप्लिकेशन देखें जो सभी फ़ाइलों को ऐक्सेस कर सकते हैं"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 दिन}one{# दिन}other{# दिन}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# घंटा}one{# घंटा}other{# घंटे}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"नोट लिखने के लिए ऐप्लिकेशन"</string> <string name="role_notes_description" msgid="8496852798616883551">"आपके डिवाइस पर नोट लिखने की सुविधा देने वाले ऐप्लिकेशन"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"नोट"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"डिफ़ॉल्ट वॉलेट ऐप्लिकेशन"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"वॉलेट ऐप्लिकेशन"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"वॉलेट ऐप्लिकेशन में, अलग-अलग तरह के लेन-देन में इस्तेमाल होने वाली चीज़ों को स्टोर किया जा सकता है. जैसे, क्रेडिट कार्ड, लॉयल्टी कार्ड, कार की डिजिटल कुंजी वगैरह."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"क्या <xliff:g id="APP_NAME">%1$s</xliff:g> को अपने डिफ़ॉल्ट वॉलेट ऐप्लिकेशन के तौर पर सेट करना है?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"अनुमति लेना ज़रूरी नहीं है"</string> <string name="request_role_current_default" msgid="738722892438247184">"मौजूदा डिफ़ॉल्ट"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"फिर से न पूछें"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"डिफ़ॉल्ट के रूप में सेट करें"</string> @@ -458,7 +465,7 @@ <string name="assistant_record_audio_user_sensitive_summary" msgid="6482937591816401619">"आवाज़ से डिवाइस का इस्तेमाल करने के लिए, माइक्रोफ़ोन का इस्तेमाल करते समय स्थिति बार में आइकॉन दिखाएं"</string> <string name="permgrouprequest_storage_isolated" msgid="4892154224026852295">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को अपने डिवाइस में मौजूद फ़ोटो और मीडिया ऐक्सेस करने की अनुमति देनी है?"</string> <string name="permgrouprequest_device_aware_storage_isolated" msgid="5934218468708513375">"क्या <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपके <b><xliff:g id="DEVICE">%2$s</xliff:g></b> में मौजूद फ़ोटो और मीडिया का ऐक्सेस देना है?"</string> - <string name="permgrouprequest_contacts" msgid="8391550064551053695">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को अपने संपर्क देखने की अनुमति देनी है?"</string> + <string name="permgrouprequest_contacts" msgid="8391550064551053695">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपके संपर्क का ऐक्सेस देना है?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"क्या <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपके <b><xliff:g id="DEVICE">%2$s</xliff:g></b> में मौजूद, संपर्कों का ऐक्सेस देना है?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को इस डिवाइस की जगह की जानकारी ऐक्सेस करने की अनुमति देनी है?"</string> <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"क्या <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपके <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> की जगह की जानकारी का ऐक्सेस देना है?"</string> @@ -512,7 +519,7 @@ <string name="permgroupupgraderequest_camera" msgid="640758449200241582">"क्या आप <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> के लिए, कैमरे के ऐक्सेस की अनुमति बदलना चाहते हैं?"</string> <string name="permgroupupgraderequest_device_aware_camera" msgid="4198765626608612156">"क्या <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> के लिए, आपके <b><xliff:g id="DEVICE">%2$s</xliff:g></b> के कैमरे का ऐक्सेस बदलना है?"</string> <string name="permgroupupgraderequestdetail_camera" msgid="6642747548010962597">"यह ऐप्लिकेशन हर समय तस्वीरें लेना और वीडियो रिकॉर्ड करना चाहता है, तब भी जब आप ऐप्लिकेशन इस्तेमाल न कर रहे हों. "<annotation id="link">"सेटिंग में जाकर अनुमति दें."</annotation></string> - <string name="permgrouprequest_calllog" msgid="2065327180175371397">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को अपने फ़ोन के काॅल लाॅग को ऐक्सेस करने की अनुमति देनी है?"</string> + <string name="permgrouprequest_calllog" msgid="2065327180175371397">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपका कॉल लॉग ऐक्सेस करने की अनुमति देनी है?"</string> <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"क्या <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपके <b><xliff:g id="DEVICE">%2$s</xliff:g></b> में मौजूद, कॉल लॉग का ऐक्सेस देना है?"</string> <string name="permgrouprequest_phone" msgid="1829234136997316752">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को फ़ोन कॉल करने और उन्हें मैनेज करने की अनुमति देनी है?"</string> <string name="permgrouprequest_device_aware_phone" msgid="4389610977195521813">"क्या <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपके <b><xliff:g id="DEVICE">%2$s</xliff:g> से फ़ोन कॉल करने और उन्हें मैनेज करने का ऐक्सेस देना है?"</string> @@ -524,7 +531,7 @@ <string name="permgroupbackgroundrequestdetail_sensors" msgid="7726767635834043501">"इस ऐप्लिकेशन का इस्तेमाल न किए जाने पर भी, इसे बॉडी सेंसर के डेटा को हमेशा ऐक्सेस करने की अनुमति देने के लिए, "<annotation id="link">"सेटिंग पर जाएं."</annotation></string> <string name="permgroupupgraderequest_sensors" msgid="7576527638411370468">"क्या इस्तेमाल के दौरान, <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को बॉडी सेंसर के डेटा का ऐक्सेस देते रहना है?"</string> <string name="permgroupupgraderequest_device_aware_sensors" msgid="3310667992344623159">"क्या इस्तेमाल के दौरान, <b><xliff:g id="DEVICE">%2$s</xliff:g></b> पर <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को बॉडी सेंसर के डेटा का ऐक्सेस देते रहना है?"</string> - <string name="permgrouprequest_notifications" msgid="6396739062335106181">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को सूचनाएं भेजने की अनुमति दें?"</string> + <string name="permgrouprequest_notifications" msgid="6396739062335106181">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को सूचनाएं भेजने की अनुमति देनी है?"</string> <string name="permgrouprequest_device_aware_notifications" msgid="7307588961166360244">"क्या <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को आपके <b><xliff:g id="DEVICE">%2$s</xliff:g></b> पर सूचनाएं भेजने की अनुमति देनी है?"</string> <string name="auto_granted_permissions" msgid="6009452264824455892">"कंट्रोल की गई अनुमतियां"</string> <string name="auto_granted_location_permission_notification_title" msgid="7570818224669050377">"<xliff:g id="APP_NAME">%1$s</xliff:g> के पास, डिवाइस की जगह की जानकारी का ऐक्सेस है"</string> @@ -545,7 +552,7 @@ <string name="exempt_info_label" msgid="6286190981253476699">"<xliff:g id="APP_NAME">%1$s</xliff:g> को Android की मदद से सुरक्षित किया गया है. आपका डेटा इस डिवाइस पर प्रोसेस किया गया है. इसलिए, इस ऐप्लिकेशन की अनुमति के इस्तेमाल की जानकारी, प्राइवसी डैशबोर्ड पर नहीं दिखती."</string> <string name="blocked_camera_title" msgid="1128510551791284384">"डिवाइस का कैमरा ब्लॉक किया गया है"</string> <string name="blocked_microphone_title" msgid="1631517143648232585">"डिवाइस का माइक्रोफ़ोन ब्लॉक किया गया है"</string> - <string name="blocked_location_title" msgid="2005608279812892383">"डिवाइस की जगह की जानकारी की सुविधा बंद है"</string> + <string name="blocked_location_title" msgid="2005608279812892383">"डिवाइस की जगह की जानकारी की सेटिंग बंद है"</string> <string name="blocked_sensor_summary" msgid="4443707628305027375">"ऐप्लिकेशन और सेवाओं के लिए"</string> <string name="blocked_mic_summary" msgid="8960466941528458347">"जब आपातकालीन नंबर पर कॉल किया जाता है, तो माइक ब्लॉक होने के बावजूद माइक्रोफ़ोन का डेटा शेयर किया जा सकता है."</string> <string name="blocked_sensor_button_label" msgid="6742092634984289658">"बदलें"</string> @@ -648,4 +655,21 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"डेटा शेयर करने के तरीके के बारे में अपडेट"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"कुछ ऐप्लिकेशन ने आपकी जगह की जानकारी के डेटा को शेयर करने का तरीका बदल दिया है"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"सेटिंग"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> को ऐक्सेस किया गया"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"<xliff:g id="TIME_DATE">%1$s</xliff:g> को कल ऐक्सेस किया गया था"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g> को ऐक्सेस किया गया"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"एक बार इस्तेमाल होने वाला पासवर्ड 132435 है"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"इस सेटिंग पर पाबंदी लगाई गई है"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"आपकी सुरक्षा के लिए, यह सेटिंग फ़िलहाल उपलब्ध नहीं है."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"ऐप्लिकेशन को, <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> को ऐक्सेस करने की अनुमति नहीं मिली"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"इस ऐप्लिकेशन ने संवेदनशील जानकारी ऐक्सेस करने का अनुरोध किया है. इसे अनुमति देने पर, आपकी निजी और वित्तीय जानकारी की सुरक्षा को खतरा हो सकता है.<xliff:g id="ID_1"><br><br></xliff:g>हालांकि, हो सकता है कि पाबंदी वाली अनुमति न मिलने पर, ऐप्लिकेशन सही तरह से काम न करें. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ऐक्सेस देने का तरीका जानें</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ऐप्लिकेशन को, डिफ़ॉल्ट <xliff:g id="ROLE_NAME">%1$s</xliff:g> के तौर पर सेट करने की अनुमति नहीं मिली"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"इस ऐप्लिकेशन ने संवेदनशील जानकारी ऐक्सेस करने का अनुरोध किया है. इसे अनुमति देने पर, आपकी निजी और वित्तीय जानकारी की सुरक्षा को खतरा हो सकता है.<xliff:g id="ID_1"><br><br></xliff:g>हालांकि, हो सकता है कि पाबंदी वाली अनुमतियां न मिलने पर, ऐप्लिकेशन सही तरह से काम न करें. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ऐक्सेस देने का तरीका जानें</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ऐप्लिकेशन को अनुमति नहीं मिली"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ऐप्लिकेशन को यह अनुमति मिलने पर, आपकी निजी और वित्तीय जानकारी की सुरक्षा को खतरा हो सकता है.<xliff:g id="ID_1"><br><br></xliff:g>हालांकि, हो सकता है कि पाबंदी वाली अनुमति न मिलने पर, ऐप्लिकेशन सही तरह से काम न करें. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ऐक्सेस देने का तरीका जानें</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ज़्यादा जानें"</string> + <!-- no translation found for enhanced_confirmation_dialog_ok (8560373821598619924) --> + <skip /> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"अनुमति का अनुरोध अस्वीकार किया गया"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"यह ऐप्लिकेशन ज़्यादा अनुमतियों का अनुरोध कर रहा है. हालांकि, स्ट्रीमिंग सेशन के दौरान अनुमतियां नहीं दी जा सकतीं. सबसे पहले अपने फ़ोन पर अनुमति दें."</string> </resources> diff --git a/PermissionController/res/values-hr-v34/strings.xml b/PermissionController/res/values-hr-v34/strings.xml index 74a1d7d1e..df017c05d 100644 --- a/PermissionController/res/values-hr-v34/strings.xml +++ b/PermissionController/res/values-hr-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Upravljajte kojim podacima o zdravlju pristupaju aplikacije"</string> <string name="location_settings" msgid="8863940440881290182">"Pristup lokaciji"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Za aplikacije i usluge. Ako je ta postavka isključena, podaci mikrofona i dalje se mogu dijeliti kad nazovete broj hitne službe"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Za aplikacije i usluge"</string> </resources> diff --git a/PermissionController/res/values-hr-watch/strings.xml b/PermissionController/res/values-hr-watch/strings.xml index cb04d90e9..3e1f56a9a 100644 --- a/PermissionController/res/values-hr-watch/strings.xml +++ b/PermissionController/res/values-hr-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Promjena nemoguća"</string> <string name="generic_yes" msgid="2489207724988649846">"Da"</string> <string name="generic_cancel" msgid="2631708607129269698">"Otkaži"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Cijelo vrijeme"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Dok se aplikacija koristi"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Cijelo vrijeme"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Dok se aplikacija koristi"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Cijelo vrijeme"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Dok se aplikacija koristi"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Cijelo vrijeme"</string> </resources> diff --git a/PermissionController/res/values-hr/strings.xml b/PermissionController/res/values-hr/strings.xml index d45180846..422c02a4e 100644 --- a/PermissionController/res/values-hr/strings.xml +++ b/PermissionController/res/values-hr/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Sva dopuštenja"</string> <string name="other_permissions" msgid="2901186127193849594">"Ostale mogućnosti aplikacije"</string> <string name="permission_request_title" msgid="8790310151025020126">"Zahtijevanje dopuštenja"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Radnje instaliranja i deinstaliranja nisu podržane na Wearu."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Odaberite čemu će <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> moći pristupiti"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ažurirana je. Odaberite čemu će moći pristupiti."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Otkaži"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kad je točna lokacija isključena, aplikacije mogu pristupiti vašoj približnoj lokaciji"</string> <string name="app_permission_title" msgid="2090897901051370711">"Dopuštenje <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Pristup aplikacije značajci \"<xliff:g id="PERM">%1$s</xliff:g>\""</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Pristup značajke <xliff:g id="PERM">%1$s</xliff:g> za ovu aplikaciju na uređaju <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Pogledajte sva dopuštenja aplikacije <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Pogledajte sve aplikacije s tim dopuštenjem"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Prikaz korištenja mikrofona Asistenta"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Ukloni dopuštenja ako se aplikacija ne upotrebljava"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Ukloni dopuštenja i oslobodi prostor"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pauziraj aktivnosti u aplikacijama ako se ne koriste"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Upravljajte nekorištenom aplikacijom"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Uklonite dopuštenja, izbrišite privremene datoteke i zaustavite obavijesti"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Uklonite dopuštenja, izbrišite privremene datoteke, zaustavite obavijesti i arhivirajte aplikaciju"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Kako bi se vaši podaci zaštitili, dopuštenja za ovu aplikaciju uklonit će se ako se aplikacija ne upotrebljava nekoliko mjeseci."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Kako bi se vaši podaci zaštitili, ako se aplikacija ne upotrebljava nekoliko mjeseci, uklonit će se sljedeća dopuštenja: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Radi zaštite vaših podataka uklonjena su dopuštenja aplikacijama koje nekoliko mjeseci niste upotrebljavali."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Dopušteno upravljanje svim datotekama"</string> <string name="ask_header" msgid="2633816846459944376">"Pitaj svaki put"</string> <string name="denied_header" msgid="903209608358177654">"Nemaju dopuštenje"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Pogledajte koje još aplikacije imaju pristup svim datotekama"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dan}one{# dan}few{# dana}other{# dana}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# sat}one{# sat}few{# sata}other{# sati}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikacija za bilješke"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikacije koje vam omogućuju vođenje bilješki na uređaju"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"napomene"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Zadana aplikacija za novčanik"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikacija za novčanik"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplikacije za novčanik mogu pohraniti vaše kreditne kartice i kartice vjernosti, automobilske ključeve i druge stvari kako bi vam razne vrste transakcija bile praktičnije."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Želite li aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> postaviti kao zadanu aplikaciju za novčanik?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Dopuštenja nisu potrebna"</string> <string name="request_role_current_default" msgid="738722892438247184">"Trenutačna zadana"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Više me ne pitaj"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Postavi kao zadano"</string> @@ -488,7 +495,7 @@ <string name="permgrouprequest_storage_pre_q" msgid="168130651144569428">"Dopustiti apl. <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristup <b>foto/video/audio i drugim datotekama te glazbi</b> na uređaju?"</string> <string name="permgrouprequest_read_media_aural" msgid="2593365397347577812">"Želite li dopustiti aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristup glazbi i audiodatotekama na ovom uređaju?"</string> <string name="permgrouprequest_device_aware_read_media_aural" msgid="3331524384339036668">"Dopustiti da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa glazbi i audiodatotekama na uređaju <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"Želite li aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dopustiti pristup fotografijama i videozapisima na ovom uređaju?"</string> + <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"Želite li aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dopustiti da pristupa fotografijama i videozapisima na ovom uređaju?"</string> <string name="permgrouprequest_device_aware_read_media_visual" msgid="5492319750632751551">"Dopustiti da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa fotografijama i videozapisima na uređaju <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_more_photos" msgid="128933814654231321">"Želite li aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dopustiti pristup većem broju fotografija i videozapisa na ovom uređaju?"</string> <string name="permgrouprequest_device_aware_more_photos" msgid="8946782319103584021">"Dopustiti da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa većem broju fotografija i videozapisa na uređaju <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> @@ -534,7 +541,7 @@ <string name="not_used_permissions_description" msgid="7595514824169388718">"Dopuštenja koja upotrebljavaju samo aplikacije sustava."</string> <string name="additional_permissions_label" msgid="7693557637462569046">"Dodatna dopuštenja"</string> <string name="additional_permissions_description" msgid="2186611950890732112">"Dopuštenja koja definiraju aplikacije."</string> - <string name="privdash_label_camera" msgid="1426440033626198096">"Fotoaparat"</string> + <string name="privdash_label_camera" msgid="1426440033626198096">"Kamera"</string> <string name="privdash_label_microphone" msgid="8415035835803511693">"Mikrofon"</string> <string name="privdash_label_location" msgid="6882400763866489291">"Lokacija"</string> <string name="privdash_label_other" msgid="3710394147423236033">"Drugo"</string> @@ -564,7 +571,7 @@ <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Provjera statusa"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Vaše kontrole privatnosti"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"Više postavki"</string> - <string name="camera_toggle_label_qs" msgid="3880261453066157285">"Pristup fotoaparatu"</string> + <string name="camera_toggle_label_qs" msgid="3880261453066157285">"Pristup kameri"</string> <string name="microphone_toggle_label_qs" msgid="8132912469813396552">"Pristup mikrofonu"</string> <string name="permissions_removed_qs" msgid="8957319130625294572">"Dopuštenje uklonjeno"</string> <string name="camera_usage_qs" msgid="4394233566086665994">"Prikaži nedavnu upotrebu fotoaparata"</string> @@ -606,7 +613,7 @@ <string name="safety_center_background_location_access_revoked" msgid="6972274943343442213">"Promijenjen je pristup"</string> <string name="safety_center_view_recent_location_access" msgid="3524391299490678243">"Prikaži nedavnu upotrebu lokacije"</string> <string name="privacy_controls_title" msgid="7605929972256835199">"Kontrole privatnosti"</string> - <string name="camera_toggle_title" msgid="1251201397431837666">"Pristup fotoaparatu"</string> + <string name="camera_toggle_title" msgid="1251201397431837666">"Pristup kameri"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"Pristup mikrofonu"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Za aplikacije i usluge"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Za aplikacije i usluge. Ako je ta postavka isključena, podaci mikrofona i dalje se mogu dijeliti kad nazovete broj hitne službe."</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Ažuriranja o dijeljenju podataka"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Neke su aplikacije promijenile način na koji mogu dijeliti vaše podatke o lokaciji"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Postavke"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Pristupljeno: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Pristupljeno jučer: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Pristupljeno: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Vaša jednokratna zaporka je 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ograničena postavka"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Radi vaše sigurnosti ova postavka trenutačno nije dostupna."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikaciji je odbijen pristup dopuštenju <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikacija je zatražila pristup dopuštenju za osjetljive podatke koje može ugroziti vaše osobne i financijske podatke.<xliff:g id="ID_1"><br><br></xliff:g>Moguće je da aplikacija neće pravilno funkcionirati bez tog ograničenog dopuštenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako omogućiti pristup</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikaciji je odbijen pristup da prema zadanim postavkama bude <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikacija je zatražila pristup dopuštenjima za osjetljive podatke koja mogu ugroziti vaše osobne i financijske podatke.<xliff:g id="ID_1"><br><br></xliff:g>Moguće je da aplikacija neće pravilno funkcionirati bez tih ograničenih dopuštenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako omogućiti pristup</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikaciji je odbijen pristup"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Pristup tom dopuštenju može ugroziti vaše osobne i financijske podatke.<xliff:g id="ID_1"><br><br></xliff:g>Moguće je da aplikacija neće pravilno funkcionirati bez tog ograničenog dopuštenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saznajte kako omogućiti pristup</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Saznajte više"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"U redu"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Upit za dopuštenje je spriječen"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Aplikacija zahtijeva dodatna dopuštenja, no dopuštenja se ne mogu odobriti u sesiji streaminga. Dopuštenje najprije odobrite na telefonu."</string> </resources> diff --git a/PermissionController/res/values-hu-v34/strings.xml b/PermissionController/res/values-hu-v34/strings.xml index 1a01b1cc0..b9c4af390 100644 --- a/PermissionController/res/values-hu-v34/strings.xml +++ b/PermissionController/res/values-hu-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Az egészségügyi adatokhoz való alkalmazás-hozzáférés kezelése"</string> <string name="location_settings" msgid="8863940440881290182">"Helyhozzáférés"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Alkalmazásoknál és szolgáltatásoknál. Ha ki van kapcsolva ez a beállítás, segélyhívó szám hívásakor a rendszer továbbra is megoszthatja a mikrofonadatokat."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Alkalmazásoknál és szolgáltatásoknál"</string> </resources> diff --git a/PermissionController/res/values-hu-watch/strings.xml b/PermissionController/res/values-hu-watch/strings.xml index 6022530fa..54ef0998b 100644 --- a/PermissionController/res/values-hu-watch/strings.xml +++ b/PermissionController/res/values-hu-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Nem változtatható"</string> <string name="generic_yes" msgid="2489207724988649846">"Igen"</string> <string name="generic_cancel" msgid="2631708607129269698">"Mégse"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Mindig"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Az app használata közben"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Mindig"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Az app használata közben"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Mindig"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Az app használata közben"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Mindig"</string> </resources> diff --git a/PermissionController/res/values-hu/strings.xml b/PermissionController/res/values-hu/strings.xml index c47c9ee9f..500012cc2 100644 --- a/PermissionController/res/values-hu/strings.xml +++ b/PermissionController/res/values-hu/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Az összes engedély"</string> <string name="other_permissions" msgid="2901186127193849594">"Egyéb alkalmazáslehetőségek"</string> <string name="permission_request_title" msgid="8790310151025020126">"Engedélykérés"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"A Wear nem támogatja a telepítés/eltávolítás műveletet."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Válassza ki, hogy a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mihez férjen hozzá"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"A(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> frissítése megtörtént. Válassza ki, hogy mihez férjen hozzá ez az alkalmazás."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Mégse"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Ha a pontos hely ki van kapcsolva, akkor az alkalmazások az Ön hozzávetőleges tartózkodási helyéhez férhetnek hozzá"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> – engedély"</string> <string name="app_permission_header" msgid="2951363137032603806">"Alkalmazás hozzáférése a következőhöz: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> – hozzáférés az alkalmazás számára a(z) <xliff:g id="DEVICE_NAME">%2$s</xliff:g> eszközön"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"A(z) <xliff:g id="APP">%1$s</xliff:g> összes engedélyének megtekintése"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Az ezzel az engedéllyel rendelkező összes alkalmazás megtekintése"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mikrofon Segéd általi használatának megjelenítése"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Engedélyek eltávolítása, ha nem használja az alkalmazást"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Engedélytörlés és tárhely-felszabadítás"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"App szüneteltetése, ha nem használja"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Nem használt alkalmazás kezelése"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Engedélyek eltávolítása, ideiglenes fájlok törlése és értesítések leállítása"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Engedélyek eltávolítása, ideiglenes fájlok törlése, értesítések leállítása és az alkalmazás archiválása"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Az adatok védelme érdekében az ennek az alkalmazásnak adott engedélyek visszavonásra kerülnek, ha néhány hónapon át nem használja az alkalmazást."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Ha néhány hónapon át nem használja az alkalmazást, az adatok védelme érdekében a rendszer visszavonja a következő engedélyeket: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Az adatok védelme érdekében a rendszer eltávolította a néhány hónapja nem használt alkalmazások engedélyeit."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Engedélyezve az összes fájl kezeléséhez"</string> <string name="ask_header" msgid="2633816846459944376">"Mindig kérdezzen rá"</string> <string name="denied_header" msgid="903209608358177654">"Nem engedélyezett"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"További, minden fájlhoz hozzáférő alkalmazások megtekintése"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 nap}other{# nap}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# óra}other{# óra}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Jegyzetkészítő alkalmazás"</string> <string name="role_notes_description" msgid="8496852798616883551">"Alkalmazások, amelyek lehetővé teszik, hogy jegyzeteket készítsen az eszközén."</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"jegyzetek"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Alapértelmezett Wallet-app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet-app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"A Wallet-alkalmazások tárolhatják a hitel- és hűségkártyákat, az autókulcsokat és egyebeket a tranzakciók különböző formáinak támogatása érdekében."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> beállítása alapértelmezett Wallet-appként?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nincs szükség engedélyre"</string> <string name="request_role_current_default" msgid="738722892438247184">"Aktuális alapérték"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ne jelenjen meg többé"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Alapértelmezett"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Adatmegosztási frissítések"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Egyes alkalmazások módosították, hogy miként oszthatják meg az Ön helyadatait"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Beállítások"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Hozzáférés: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Hozzáférés: tegnap, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Hozzáférés: <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Az Ön egyszer használatos jelszava: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Korlátozott beállítás"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Biztonsága érdekében ez a beállítás jelenleg nem használható."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Az app nem kapott hozzáférést a következőhöz: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Az alkalmazás hozzáférési engedélyt kért a bizalmas adatokhoz, ami veszélybe sodorhatja az Ön személyes és pénzügyi adatait.<xliff:g id="ID_1"><br><br></xliff:g>Lehetséges, hogy az alkalmazás nem működik megfelelően enélkül a korlátozott engedély nélkül. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>További információ a hozzáférés megadásának módjáról.</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Az app nem kapott hozzáférést a következőhöz: alapértelmezett <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Az alkalmazás hozzáférési engedélyt kért a bizalmas adatokhoz, ami veszélybe sodorhatja az Ön személyes és pénzügyi adatait.<xliff:g id="ID_1"><br><br></xliff:g>Lehetséges, hogy az alkalmazás nem működik megfelelően ezen korlátozott engedélyek nélkül. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>További információ a hozzáférés megadásának módjáról.</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Az alkalmazás nem kapott hozzáférést"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Az ehhez az engedélyhez való hozzáférés veszélybe sodorhatja az Ön személyes és pénzügyi adatait.<xliff:g id="ID_1"><br><br></xliff:g>Lehetséges, hogy az alkalmazás nem működik megfelelően enélkül a korlátozott engedély nélkül. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>További információ a hozzáférés megadásának módjáról.</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"További információ"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Engedélykérés letiltva"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ez az alkalmazás további engedélyeket kér, de az engedélyeket nem lehet megadni streamelési munkamenetben. Előbb adja meg az engedélyeket a telefonján."</string> </resources> diff --git a/PermissionController/res/values-hy-v34/strings.xml b/PermissionController/res/values-hy-v34/strings.xml index fb8997eb1..20d4b3b5e 100644 --- a/PermissionController/res/values-hy-v34/strings.xml +++ b/PermissionController/res/values-hy-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Կառավարեք առողջության մասին տվյալների հասանելիությունը հավելվածների համար"</string> <string name="location_settings" msgid="8863940440881290182">"Տեղորոշման թույլտվություն"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Հավելվածների և ծառայությունների համար։ Եթե այս կարգավորումն անջատված է, խոսափողի տվյալները միևնույն է կարող են փոխանցվել, երբ զանգեք արտակարգ իրավիճակների որևէ հեռախոսահամարի"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Հավելվածների և ծառայությունների համար"</string> </resources> diff --git a/PermissionController/res/values-hy-watch/strings.xml b/PermissionController/res/values-hy-watch/strings.xml index 77f8f5afe..b62e2d035 100644 --- a/PermissionController/res/values-hy-watch/strings.xml +++ b/PermissionController/res/values-hy-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Հնարավոր չէ փոխել"</string> <string name="generic_yes" msgid="2489207724988649846">"Այո"</string> <string name="generic_cancel" msgid="2631708607129269698">"Չեղարկել"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Միշտ"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Հավելվածն օգտագործելիս"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Միշտ"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Հավելվածն օգտագործելիս"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Միշտ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Հավելվածն օգտագործելիս"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Միշտ"</string> </resources> diff --git a/PermissionController/res/values-hy/strings.xml b/PermissionController/res/values-hy/strings.xml index 8d92099d2..0394108f2 100644 --- a/PermissionController/res/values-hy/strings.xml +++ b/PermissionController/res/values-hy/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Բոլոր թույլտվությունները"</string> <string name="other_permissions" msgid="2901186127193849594">"Էլ ինչ կարող է անել հավելվածը"</string> <string name="permission_request_title" msgid="8790310151025020126">"Թույլտվության հարցում"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Տեղադրման/հեռացման գործողությունները Android Wear-ում չեն աջակցվում:"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Ընտրեք՝ ինչ թույլտվություններ եք ուզում տրամադրել <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածը թարմացվել է: Ընտրեք՝ ինչ թույլտվություններ եք ուզում տրամադրել այդ հավելվածին:"</string> <string name="review_button_cancel" msgid="2191147944056548886">"Չեղարկել"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Եթե ճշգրիտ տեղադրությունն անջատված է, հավելվածին հասանելի է ձեր մոտավոր գտնվելու վայրը"</string> <string name="app_permission_title" msgid="2090897901051370711">"«<xliff:g id="PERM">%1$s</xliff:g>» թույլտվություն"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> օգտագործելու թույլտվություն այս հավելվածի համար"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g>ն օգտագործելու թույլտվություն այս հավելվածի համար <xliff:g id="DEVICE_NAME">%2$s</xliff:g> սարքում"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Տեսնել «<xliff:g id="APP">%1$s</xliff:g>» հավելվածի բոլոր թույլտվությունները"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Դիտել այս թույլտվությունն ունեցող հավելվածների ցանկը"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Ցույց տալ օգնականի կողմից խոսափողի օգտագործման վիճակագրությունը"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Հեռացնել թույլտվությունները, եթե հավելվածը չի օգտագործվում"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Հեռացնել թույլտվությունները և տարածք ազատել"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Դադարեցնել աշխատանքը ոչ ակտիվ վիճակում"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Կառավարել հավելվածը, եթե չի օգտագործվում"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Հեռացնել թույլտվությունները, ջնջել ժամանակավոր ֆայլերը և դադարեցնել ծանուցումները"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Հեռացնել թույլտվությունները, ջնջել ժամանակավոր ֆայլերը, դադարեցնել ծանուցումները և արխիվացնել հավելվածը"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Եթե հավելվածը չի օգտագործվել մի քանի ամիս, դրա թույլտվությունները կհեռացվեն՝ ձեր տվյալները պաշտպանելու համար։"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Եթե հավելվածը չի օգտագործվել մի քանի ամիս, ձեր տվյալները պաշտպանելու համար հետևյալ թույլտվությունները կհեռացվեն՝ <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Հավելվածներից, որոնք մի քանի ամիս չեք օգտագործել, թույլտվությունները հեռացվել են՝ ձեր տվյալները պաշտպանելու համար։"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Հավելվածներ, որոնց հասանելի են բոլոր ֆայլերը"</string> <string name="ask_header" msgid="2633816846459944376">"Ամեն անգամ հարցնել"</string> <string name="denied_header" msgid="903209608358177654">"Արգելված"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> սարքում"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Տեսնել այլ հավելվածներ, որոնց հասանելի են բոլոր ֆայլերը"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 օր}one{# օր}other{# օր}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ժամ}one{# ժամ}other{# ժամ}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Նշումների հավելված"</string> <string name="role_notes_description" msgid="8496852798616883551">"Հավելվածներ, որոնք թույլ են տալիս նշումներ ստեղծել ձեր սարքում"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"նշումներ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Դրամապանակի կանխադրվ. հավելված"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Դրամապանակի հավելված"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Դրամապանակի հավելվածները կարող են պահել ձեր վարկային և մշտական հաճախորդի քարտերը, մեքենայի բանալիները և այլ բաներ, որոնք կհեշտացնեն ձեր գործարքները։"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Նշե՞լ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը որպես դրամապանակի կանխադրված հավելված"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Թույլտվություններ հարկավոր չեն"</string> <string name="request_role_current_default" msgid="738722892438247184">"Օգտագործվում է ըստ կանխադրման"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Նորից չհարցնել"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Նշել կանխադրված"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Թույլատրե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին օգտագործել ձեր կոնտակտները"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Թույլատրե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-ին օգտագործել ձեր կոնտակտները <b><xliff:g id="DEVICE">%2$s</xliff:g>ում</b>։"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"Թույլ տա՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին օգտագործել այս սարքի տեղադրության տվյալները"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Թույլատրե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-ին օգտագործել ձեր <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>ի</b> տեղադրության տվյալները։"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Թույլատրե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-ին օգտագործել ձեր <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ի</b> տեղադրության տվյալները"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Տեղադրության տվյալները հասանելի կլինեն հավելվածին, միայն երբ այն օգտագործելիս լինեք"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Թույլ տա՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին օգտագործել այս սարքի տեղադրության տվյալները"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Թույլատրե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-ին օգտագործել ձեր <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>ի</b> տեղադրության մասին տվյալները։"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Տվյալներով կիսվելու եղանակի փոփոխություն"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Որոշ հավելվածներ փոխել են ձեր տեղադրության տվյալներով կիսվելու եղանակը"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Կարգավորումներ"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Բացվել է <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Բացվել է երեկ, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Բացվել է <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Մեկանգամյա օգտագործման ձեր գաղտնաբառը՝ 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Սահմանափակումներով կարգավորում"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Անվտանգության նկատառումներից ելնելով՝ այս կարգավորումը ներկայումս անհասանելի է։"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Հավելվածին մերժվել է <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>ի օգտագործման թույլտվությունը"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Հավելվածը հայցել է կոնֆիդենցիալ տեղեկությունների օգտագործման թույլտվություն, որը կարող է վտանգի ենթարկել ձեր անձնական և ֆինանսական տեղեկությունները։<xliff:g id="ID_1"><br><br></xliff:g>Հնարավոր է, որ առանց այս սահմանափակված թույլտվության՝ հավելվածը չաշխատի պատշաճ կերպով։ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ինչպես տրամադրել տվյալների օգտագործման թույլտվություն</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Հավելվածին մերժվել է «<xliff:g id="ROLE_NAME">%1$s</xliff:g>» կատեգորիայում կանխադրված լինելու թույլտվությունը"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Հավելվածը հայցել է կոնֆիդենցիալ տեղեկությունների օգտագործման թույլտվություններ, որոնք կարող են վտանգի ենթարկել ձեր անձնական և ֆինանսական տեղեկությունները։<xliff:g id="ID_1"><br><br></xliff:g>Հնարավոր է, որ առանց այս սահմանափակված թույլտվությունների՝ հավելվածը չաշխատի պատշաճ կերպով։ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ինչպես տրամադրել տվյալների օգտագործման թույլտվություն</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Հավելվածին մերժվել է թույլտվությունը"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Եթե տրամադրեք այս թույլտվությունը, ձեր անձնական և ֆինանսական տեղեկությունները կարող են վտանգված լինել։<xliff:g id="ID_1"><br><br></xliff:g>Հնարավոր է, որ առանց այս սահմանափակված թույլտվության՝ հավելվածը չաշխատի պատշաճ կերպով։ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ինչպես տրամադրել տվյալների օգտագործման թույլտվություն</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Իմանալ ավելին"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Եղավ"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Թույլտվության հայտն արգելափակվել է"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Այս հավելվածը պահանջում է լրացուցիչ թույլտվություններ, սակայն դրանք հնարավոր չէ տրամադրել հեռարձակման ժամանակ։ Նախ տրամադրեք թույլտվությունը ձեր հեռախոսում։"</string> </resources> diff --git a/PermissionController/res/values-in-v33/strings.xml b/PermissionController/res/values-in-v33/strings.xml index b74e806df..90be234ea 100644 --- a/PermissionController/res/values-in-v33/strings.xml +++ b/PermissionController/res/values-in-v33/strings.xml @@ -27,7 +27,7 @@ <string name="safety_center_entry_group_with_actions_needed_content_description" msgid="2708884606775932657">"Daftar. <xliff:g id="ENTRY_TITLE">%1$s</xliff:g>. Diperlukan tindakan. <xliff:g id="ENTRY_SUMMARY">%2$s</xliff:g>"</string> <string name="safety_center_entry_group_item_content_description" msgid="7348298582877249787">"Item daftar. <xliff:g id="ENTRY_ITEM_TITLE">%1$s</xliff:g>. <xliff:g id="ENTRY_ITEM_SUMMARY">%2$s</xliff:g>"</string> <string name="safety_center_entry_content_description" msgid="3639565652938224321">"<xliff:g id="ENTRY_ITEM_TITLE">%1$s</xliff:g>. <xliff:g id="ENTRY_ITEM_SUMMARY">%2$s</xliff:g>"</string> - <string name="safety_center_more_issues_card_title" msgid="7425844746197493312">"Peringatan lainnya"</string> + <string name="safety_center_more_issues_card_title" msgid="7425844746197493312">"Peringatan lain"</string> <string name="safety_center_dismissed_issues_card_title" msgid="2340129842725145733">"Peringatan yang ditutup"</string> <string name="safety_center_more_issues_card_expand_action" msgid="7109451851052272946">"{count,plural, =1{Luaskan untuk melihat satu peringatan lain}other{Luaskan untuk melihat # peringatan lain}}"</string> <string name="safety_center_issue_card_prefix_content_description" msgid="1447445289637043544">"Peringatan. <xliff:g id="ISSUE_CARD_TITLE">%1$s</xliff:g>"</string> diff --git a/PermissionController/res/values-in-v34/strings.xml b/PermissionController/res/values-in-v34/strings.xml index 7e0c0a609..f6855807d 100644 --- a/PermissionController/res/values-in-v34/strings.xml +++ b/PermissionController/res/values-in-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Kelola akses aplikasi ke data kesehatan"</string> <string name="location_settings" msgid="8863940440881290182">"Akses lokasi"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Untuk aplikasi dan layanan. Jika setelan ini nonaktif, data mikrofon mungkin tetap dibagikan saat Anda menelepon nomor darurat"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Untuk aplikasi dan layanan"</string> </resources> diff --git a/PermissionController/res/values-in-watch/strings.xml b/PermissionController/res/values-in-watch/strings.xml index 91c107aa0..c124feda4 100644 --- a/PermissionController/res/values-in-watch/strings.xml +++ b/PermissionController/res/values-in-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Tidak dapat diubah"</string> <string name="generic_yes" msgid="2489207724988649846">"Ya"</string> <string name="generic_cancel" msgid="2631708607129269698">"Batal"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Semua"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Saat menggunakan aplikasi"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Semua"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Saat menggunakan aplikasi"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Semua"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Saat menggunakan aplikasi"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Semua"</string> </resources> diff --git a/PermissionController/res/values-in/strings.xml b/PermissionController/res/values-in/strings.xml index 37df6c326..a6f929118 100644 --- a/PermissionController/res/values-in/strings.xml +++ b/PermissionController/res/values-in/strings.xml @@ -50,12 +50,12 @@ <string name="permission_revoked_all" msgid="3397649017727222283">"semua dinonaktifkan"</string> <string name="permission_revoked_none" msgid="9213345075484381180">"tidak ada yang dinonaktifkan"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"Izinkan"</string> - <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Izinkan sepanjang waktu"</string> + <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Selalu izinkan"</string> <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Saat aplikasi digunakan"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"Ubah ke lokasi presisi"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"Tetap gunakan perkiraan"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"Hanya kali ini"</string> - <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"Izinkan sepanjang waktu"</string> + <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"Selalu izinkan"</string> <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"Izinkan pengelolaan semua file"</string> <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"Izinkan akses ke file media"</string> <string name="app_permissions_breadcrumb" msgid="5136969550489411650">"Aplikasi"</string> @@ -109,15 +109,13 @@ <!-- no translation found for background_access_chooser_dialog_choices:0 (1351721623256561996) --> <!-- no translation found for background_access_chooser_dialog_choices:1 (9127301153688725448) --> <!-- no translation found for background_access_chooser_dialog_choices:2 (4305536986042401191) --> - <string name="permission_access_always" msgid="1474641821883823446">"Izinkan sepanjang waktu"</string> + <string name="permission_access_always" msgid="1474641821883823446">"Selalu izinkan"</string> <string name="permission_access_only_foreground" msgid="7801170728159326195">"Izinkan saat aplikasi digunakan"</string> <string name="permission_access_never" msgid="4647014230217936900">"Jangan izinkan"</string> <string name="loading" msgid="4789365003890741082">"Memuat…"</string> <string name="all_permissions" msgid="6911125611996872522">"Semua izin"</string> <string name="other_permissions" msgid="2901186127193849594">"Kemampuan aplikasi lainnya"</string> <string name="permission_request_title" msgid="8790310151025020126">"Permintaan izin"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Instal/Uninstal tidak didukung di Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Pilih item yang boleh diakses oleh <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> telah diperbarui. Pilih item yang boleh diakses oleh aplikasi ini."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Batal"</string> @@ -188,8 +186,8 @@ <string name="app_permission_button_allow" msgid="5808039516494774647">"Izinkan"</string> <string name="app_permission_button_allow_all_files" msgid="1792232272599018825">"Izinkan pengelolaan semua file"</string> <string name="app_permission_button_allow_media_only" msgid="2834282724426046154">"Izinkan akses hanya ke media"</string> - <string name="app_permission_button_allow_always" msgid="4573292371734011171">"Izinkan sepanjang waktu"</string> - <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"Izinkan hanya saat aplikasi digunakan"</string> + <string name="app_permission_button_allow_always" msgid="4573292371734011171">"Selalu izinkan"</string> + <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"Izinkan saat aplikasi digunakan"</string> <string name="app_permission_button_always_allow_all" msgid="4905699259378428855">"Selalu izinkan semua"</string> <string name="app_permission_button_ask" msgid="3342950658789427">"Selalu tanya"</string> <string name="app_permission_button_deny" msgid="6016454069832050300">"Jangan izinkan"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Saat lokasi presisi dinonaktifkan, aplikasi dapat mengakses perkiraan lokasi"</string> <string name="app_permission_title" msgid="2090897901051370711">"Izin <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Akses <xliff:g id="PERM">%1$s</xliff:g> untuk aplikasi ini"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Akses <xliff:g id="PERM">%1$s</xliff:g> untuk aplikasi ini di <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Lihat semua izin <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Lihat semua aplikasi yang memiliki izin ini"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Tampilkan penggunaan mikrofon Asisten"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Hapus izin jika aplikasi tidak digunakan"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Hapus izin & kosongkan ruang penyimpanan"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Jeda aktivitas aplikasi jika tak dipakai"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Kelola aplikasi jika tidak digunakan"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Hapus izin dan file sementara, serta hentikan notifikasi"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Hapus izin dan file sementara, hentikan notifikasi, dan arsipkan aplikasi"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Untuk melindungi data Anda, izin aplikasi ini akan dihapus jika aplikasi tidak digunakan dalam beberapa bulan."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Untuk melindungi data Anda, izin berikut akan dihapus jika aplikasi tidak digunakan dalam beberapa bulan: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Untuk melindungi data Anda, izin dari aplikasi yang tidak digunakan dalam beberapa bulan telah dihapus."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Diizinkan untuk mengelola semua file"</string> <string name="ask_header" msgid="2633816846459944376">"Selalu tanya"</string> <string name="denied_header" msgid="903209608358177654">"Tidak diizinkan"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> di <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Lihat aplikasi lain yang dapat mengakses semua file"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 hari}other{# hari}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# jam}other{# jam}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikasi catatan"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikasi untuk membuat catatan di perangkat"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"catatan"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Aplikasi dompet default"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikasi dompet"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplikasi dompet dapat menyimpan kartu kredit dan kartu loyalitas, kunci mobil, serta hal lainnya untuk membantu berbagai bentuk transaksi."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Setel <xliff:g id="APP_NAME">%1$s</xliff:g> sebagai aplikasi dompet default?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Tidak ada izin yang diperlukan"</string> <string name="request_role_current_default" msgid="738722892438247184">"Default saat ini"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Jangan tanya lagi"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Jadikan default"</string> @@ -648,4 +655,21 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Pembaruan berbagi data"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Beberapa aplikasi mengubah caranya berbagi data lokasi Anda"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Setelan"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Diakses <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Diakses kemarin <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Diakses <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Sandi sekali pakai Anda adalah 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Setelan terbatas"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Demi keamanan Anda, setelan ini tidak tersedia untuk saat ini."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikasi ditolak aksesnya ke <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikasi meminta akses ke izin sensitif yang dapat membahayakan info pribadi dan keuangan Anda.<xliff:g id="ID_1"><br><br></xliff:g>Aplikasi mungkin tidak dapat berfungsi dengan baik tanpa izin terbatas ini. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>&gtPelajari cara mengizinkan akses</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikasi ditolak aksesnya untuk menjadi <xliff:g id="ROLE_NAME">%1$s</xliff:g> default"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikasi meminta akses ke izin sensitif yang dapat membahayakan info pribadi dan keuangan Anda.<xliff:g id="ID_1"><br><br></xliff:g>Aplikasi mungkin tidak dapat berfungsi dengan baik tanpa izin terbatas ini. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>&gtPelajari cara mengizinkan akses</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikasi ditolak aksesnya"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Akses ke izin ini dapat membahayakan info pribadi dan keuangan Anda.<xliff:g id="ID_1"><br><br></xliff:g>Aplikasi mungkin tidak dapat berfungsi dengan baik tanpa izin terbatas ini. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>&gtPelajari cara mengizinkan akses</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Pelajari lebih lanjut"</string> + <!-- no translation found for enhanced_confirmation_dialog_ok (8560373821598619924) --> + <skip /> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Permintaan izin diblokir"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Aplikasi ini meminta izin tambahan, tetapi izin tidak dapat diberikan dalam sesi streaming. Berikan izin di ponsel terlebih dahulu."</string> </resources> diff --git a/PermissionController/res/values-is-v34/strings.xml b/PermissionController/res/values-is-v34/strings.xml index b897bcc71..11b5828c4 100644 --- a/PermissionController/res/values-is-v34/strings.xml +++ b/PermissionController/res/values-is-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Stjórna aðgangi forrita að heilsufarsgögnum"</string> <string name="location_settings" msgid="8863940440881290182">"Aðgangur að staðsetningu"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Fyrir forrit og þjónustur. Þegar slökkt er á þessari stillingu verður hljóðnemagögnum þó hugsanlega deilt þegar þú hringir í neyðarnúmer"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Fyrir forrit og þjónustur"</string> </resources> diff --git a/PermissionController/res/values-is-watch/strings.xml b/PermissionController/res/values-is-watch/strings.xml index 7f01f675c..6bfd6c7f4 100644 --- a/PermissionController/res/values-is-watch/strings.xml +++ b/PermissionController/res/values-is-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Má ekki breyta"</string> <string name="generic_yes" msgid="2489207724988649846">"Já"</string> <string name="generic_cancel" msgid="2631708607129269698">"Hætta við"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Alltaf"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Þegar forrit er notað"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Alltaf"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Þegar forrit er notað"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Alltaf"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Þegar forrit er notað"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Alltaf"</string> </resources> diff --git a/PermissionController/res/values-is/strings.xml b/PermissionController/res/values-is/strings.xml index 4a472afa0..277542ff4 100644 --- a/PermissionController/res/values-is/strings.xml +++ b/PermissionController/res/values-is/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Allar heimildir"</string> <string name="other_permissions" msgid="2901186127193849594">"Aðrir forritseiginleikar"</string> <string name="permission_request_title" msgid="8790310151025020126">"Beiðni um heimild"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Aðgerðir til að setja upp / fjarlægja eru ekki studdar í Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Veldu hverju <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> fær aðgang að"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> hefur verið uppfært. Veldu hverju forritið fær aðgang að."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Hætta við"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Þegar slökkt er á nákvæmri staðsetningu hafa forrit aðgang að áætlaðri staðsetningu"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> - heimild"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: Aðgangur fyrir þetta forrit"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Aðgangur að <xliff:g id="PERM">%1$s</xliff:g> fyrir þetta forrit í <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Sjá allar heimildir fyrir „<xliff:g id="APP">%1$s</xliff:g>“"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Sjá öll forrit með þessa heimild"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Sýna hljóðnemanotkun hjálpara"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Fjarlægja heimildir ef forrit er ekki notað"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Fjarlægja heimildir og losa um pláss"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Gera hlé á forritavirkni ef ekki notað"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Stjórna forriti ef það er ónotað"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Fjarlægja heimildir, eyða tímabundnum skrám og stöðva tilkynningar"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Fjarlægja heimildir, eyða tímabundnum skrám, stöðva tilkynningar og setja forritið í geymslu"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Til að vernda gögnin þín verða heimildir þessa forrits fjarlægðar ef það er ekki notað í nokkra mánuði."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Til að vernda gögnin þín verða eftirfarandi heimildir fjarlægðar ef forritið er ekki notað í nokkra mánuði: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Til að vernda gögnin þín voru heimildir fjarlægðar úr forritum sem þú hefur ekki notað í nokkra mánuði."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Leyfði stjórnun á öllum skrám"</string> <string name="ask_header" msgid="2633816846459944376">"Spyrja alltaf"</string> <string name="denied_header" msgid="903209608358177654">"Ekki heimilað"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> í <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Sjá fleiri forrit sem geta opnað allar skrár"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dagur}one{# dagur}other{# dagar}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# klukkustund}one{# klukkustund}other{# klukkustundir}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Glósuforrit"</string> <string name="role_notes_description" msgid="8496852798616883551">"Forrit sem gera þér kleift að taka glósur í tækinu þínu"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"glósur"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Sjálfgefið veskisforrit"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Veskisforrit"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Veskisforrit geta geymt kredit- og tryggðarkortin þín, bíllyklana og aðra hluti til að auðvelda þér að ganga frá ýmiskonar greiðslum."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Stilla <xliff:g id="APP_NAME">%1$s</xliff:g> sem sjálfgefið veskisforrit?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Engra heimilda krafist"</string> <string name="request_role_current_default" msgid="738722892438247184">"Núverandi sjálfgefið forrit"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ekki spyrja aftur"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Velja sem sjálfgefið"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Gagnadeilingaruppfærslur"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Deiling staðsetningargagna hefur breyst í sumum forritum"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Stillingar"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Opnað kl. <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Opnað í gær kl. <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Opnað <xliff:g id="TIME_DATE_0">%1$s</xliff:g> kl. <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Einnota aðgangsorðið þitt er 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Takmörkuð stilling"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Til að tryggja öryggi þitt er þessi stilling ekki tiltæk eins og er."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Forritið fékk ekki aðgang að <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Forritið bað um aðgang að heimild fyrir viðkvæmu efni sem getur sett persónu- og fjármálaupplýsingar þínar í hættu.<xliff:g id="ID_1"><br><br></xliff:g>Forritið virkar hugsanlega ekki sem skyldi án þessarar takmörkuðu heimildar. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Kynntu þér hvernig þú leyfir aðgang</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Forritið fékk ekki aðgang að sjálfgefnu <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Forritið bað um aðgang að heimildir fyrir viðkvæmu efni sem getur sett persónu- og fjármálaupplýsingar þínar í hættu.<xliff:g id="ID_1"><br><br></xliff:g>Forritið virkar hugsanlega ekki sem skyldi án þessara takmörkuðu heimilda. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Kynntu þér hvernig þú leyfir aðgang</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Forritið fékk ekki aðgang"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Aðgangur að þessari heimild getur sett persónu- og fjármálaupplýsingar þínar í hættu.<xliff:g id="ID_1"><br><br></xliff:g>Forritið virkar hugsanlega ekki sem skyldi án þessarar takmörkuðu heimildar. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Kynntu þér hvernig þú leyfir aðgang</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Nánar"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Í lagi"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Heimildarbeiðni hafnað"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Þetta forrit biður um viðbótarheimildir en ekki er hægt að veita heimildir í streymislotu. Veittu heimildina í símanum fyrst."</string> </resources> diff --git a/PermissionController/res/values-it-v34/strings.xml b/PermissionController/res/values-it-v34/strings.xml index 27da7e634..77564456c 100644 --- a/PermissionController/res/values-it-v34/strings.xml +++ b/PermissionController/res/values-it-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gestisci l\'accesso delle app ai dati sulla salute"</string> <string name="location_settings" msgid="8863940440881290182">"Accesso alla posizione"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Per app e servizi. Se questa impostazione viene disattivata, i dati del microfono potrebbero comunque essere condivisi quando chiami un numero di emergenza"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Per app e servizi"</string> </resources> diff --git a/PermissionController/res/values-it-watch/strings.xml b/PermissionController/res/values-it-watch/strings.xml index 6cb0ce756..7e5106952 100644 --- a/PermissionController/res/values-it-watch/strings.xml +++ b/PermissionController/res/values-it-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Impos. modificare"</string> <string name="generic_yes" msgid="2489207724988649846">"Sì"</string> <string name="generic_cancel" msgid="2631708607129269698">"Annulla"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Sempre"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Con app in uso"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Sempre"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Con app in uso"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Sempre"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Con app in uso"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Sempre"</string> </resources> diff --git a/PermissionController/res/values-it/strings.xml b/PermissionController/res/values-it/strings.xml index 27a1ec703..4fd98f39b 100644 --- a/PermissionController/res/values-it/strings.xml +++ b/PermissionController/res/values-it/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Tutte le autorizzazioni"</string> <string name="other_permissions" msgid="2901186127193849594">"Altre funzionalità dell\'app"</string> <string name="permission_request_title" msgid="8790310151025020126">"Richiesta di autorizzazione"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Le azioni di installazione/disinstallazione non sono supportate su Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Scegli i dati a cui l\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> può accedere"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"L\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> è stata aggiornata. Scegli i dati a cui può accedere."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Annulla"</string> @@ -195,10 +193,11 @@ <string name="app_permission_button_deny" msgid="6016454069832050300">"Non consentire"</string> <string name="precise_image_description" msgid="6349638632303619872">"Posizione esatta"</string> <string name="approximate_image_description" msgid="938803699637069884">"Posizione approssimativa"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Utilizza posizione esatta"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Posizione esatta"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Quando la posizione esatta non è attiva, le app possono accedere alla tua posizione approssimativa"</string> <string name="app_permission_title" msgid="2090897901051370711">"Autorizzazione <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Accesso a <xliff:g id="PERM">%1$s</xliff:g> per questa app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> accesso per questa app su <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Mostra tutte le autorizzazioni di <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Mostra tutte le app con questa autorizzazione"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostra utilizzo microfono dell\'assistente"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Rimuovi autorizzazioni se non in uso"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Rimuovi autorizzazioni e libera spazio"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Sospendi attività app se inutilizzata"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gestisci l\'app se inutilizzata"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Rimuovi le autorizzazioni, elimina i file temporanei e interrompi le notifiche"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Rimuovi le autorizzazioni, elimina i file temporanei, interrompi le notifiche e archivia l\'app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Per proteggere i tuoi dati, le autorizzazioni di questa app verranno rimosse se l\'app non viene usata per alcuni mesi."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Per proteggere i tuoi dati, se l\'app non viene usata per alcuni mesi, le seguenti autorizzazioni verranno rimosse: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Per proteggere i tuoi dati, sono state rimosse le autorizzazioni dalle app che non hai utilizzato per alcuni mesi."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Autorizzate per gestire tutti i file"</string> <string name="ask_header" msgid="2633816846459944376">"Chiedi ogni volta"</string> <string name="denied_header" msgid="903209608358177654">"Non autorizzata"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> su <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Visualizza altre app che possono accedere a tutti i file"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 giorno}many{# giorni}other{# giorni}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ora}many{# ore}other{# ore}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"App per le note"</string> <string name="role_notes_description" msgid="8496852798616883551">"App che ti permettono di prendere appunti sul tuo dispositivo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"note"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"App portafoglio predefinita"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"App portafoglio"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Le app portafoglio possono memorizzare carte di credito e fedeltà, chiavi della macchina e altro per facilitare varie forme di transazioni."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Impostare <xliff:g id="APP_NAME">%1$s</xliff:g> come app portafoglio predefinita?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nessuna autorizzazione necessaria"</string> <string name="request_role_current_default" msgid="738722892438247184">"Valore predefinito attuale"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Non chiedermelo più"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Imposta predefinito"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere ai tuoi contatti?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere ai contatti sul tuo <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione di questo dispositivo?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione del tuo <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b>?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione del tuo <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"L\'app avrà accesso alla posizione soltanto quando la usi"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione di questo dispositivo?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione del tuo <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Aggiornamenti relativi alla condivisione dei dati"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Alcune app hanno cambiato la modalità di condivisione dei tuoi dati sulla posizione"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Impostazioni"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Ultimo accesso: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Ultimo accesso ieri: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Ultimo accesso: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"La password monouso è: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Impostazione con limitazioni"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Per la tua sicurezza, questa impostazione non è al momento disponibile."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"All\'app è stato negato l\'accesso a <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"L\'app ha richiesto l\'accesso a un\'autorizzazione sensibile che può mettere a rischio le tue informazioni finanziarie e personali.<xliff:g id="ID_1"><br><br></xliff:g>È possibile che l\'app non funzioni correttamente senza questa autorizzazione limitata. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Scopri di più su come consentire l\'accesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"All\'app è stato negato l\'accesso al ruolo <xliff:g id="ROLE_NAME">%1$s</xliff:g> predefinita"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"L\'app ha richiesto l\'accesso ad autorizzazioni sensibili che possono mettere a rischio le tue informazioni finanziarie e personali.<xliff:g id="ID_1"><br><br></xliff:g>È possibile che l\'app non funzioni correttamente senza queste autorizzazioni limitate. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Scopri di più su come consentire l\'accesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"All\'app è stato negato l\'accesso"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"L\'accesso a questa autorizzazione può mettere a rischio le tue informazioni finanziarie e personali.<xliff:g id="ID_1"><br><br></xliff:g>È possibile che l\'app non funzioni correttamente senza questa autorizzazione limitata. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Scopri di più su come consentire l\'accesso</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Scopri di più"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Ok"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Richiesta di autorizzazione rifiutata"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Questa app richiede autorizzazioni aggiuntive, ma non è possibile concedere autorizzazioni in una sessione di streaming. Devi prima concedere l\'autorizzazione sul tuo smartphone."</string> </resources> diff --git a/PermissionController/res/values-iw-v34/strings.xml b/PermissionController/res/values-iw-v34/strings.xml index 370a20dcb..61e486e81 100644 --- a/PermissionController/res/values-iw-v34/strings.xml +++ b/PermissionController/res/values-iw-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ניהול הגישה של האפליקציות לנתוני בריאות"</string> <string name="location_settings" msgid="8863940440881290182">"גישה למיקום"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"לאפליקציות ולשירותים. אם ההגדרה מושבתת, יכול להיות שנתוני המיקרופון ישותפו בכל זאת כשתתבצע שיחה למספר חירום"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"לאפליקציות ולשירותים"</string> </resources> diff --git a/PermissionController/res/values-iw-watch/strings.xml b/PermissionController/res/values-iw-watch/strings.xml index 3db39b59b..bdf113146 100644 --- a/PermissionController/res/values-iw-watch/strings.xml +++ b/PermissionController/res/values-iw-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"לא ניתן לשנות"</string> <string name="generic_yes" msgid="2489207724988649846">"כן"</string> <string name="generic_cancel" msgid="2631708607129269698">"ביטול"</string> + <string name="permission_access_always" msgid="2107115233573823032">"כל הזמן"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"בזמן השימוש באפליקציה"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"כל הזמן"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"בזמן השימוש באפליקציה"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"כל הזמן"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"בזמן השימוש באפליקציה"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"כל הזמן"</string> </resources> diff --git a/PermissionController/res/values-iw/strings.xml b/PermissionController/res/values-iw/strings.xml index 3ab567cb3..b5afa9294 100644 --- a/PermissionController/res/values-iw/strings.xml +++ b/PermissionController/res/values-iw/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"כל ההרשאות"</string> <string name="other_permissions" msgid="2901186127193849594">"הרשאות אחרות של האפליקציה"</string> <string name="permission_request_title" msgid="8790310151025020126">"בקשת הרשאה"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"פעולות התקנה/הסרת התקנה אינן נתמכות ב-Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"בחירה בהרשאות הגישה שברצונך לתת לאפליקציה <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"אפליקציית <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> עודכנה. יש לבחור הרשאות גישה לאפליקציה הזו."</string> <string name="review_button_cancel" msgid="2191147944056548886">"ביטול"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"כשהמיקום המדויק מושבת, אפליקציות יכולות לגשת למיקום המשוער של המכשיר"</string> <string name="app_permission_title" msgid="2090897901051370711">"הרשאה: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"לאפליקציה תהיה גישה אל: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"גישה ל<xliff:g id="PERM">%1$s</xliff:g> לאפליקציה הזו ב<xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"הצגת כל ההרשאות של \'<xliff:g id="APP">%1$s</xliff:g>\'"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"הצגת כל האפליקציות עם ההרשאה הזו"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"השימוש במיקרופון של Assistant"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"הסרת ההרשאות כשלא בשימוש"</string> <string name="unused_apps_label" msgid="2595428768404901064">"הסרת הרשאות ופינוי מקום אחסון"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"השהיית הפעילות באפליקציה אם אין בה שימוש"</string> - <string name="unused_apps_summary" msgid="8839466950318403115">"ההרשאות של האפליקציה יוסרו, הקבצים הזמניים יימחקו ותופסק קבלת ההתראות ממנה"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ניהול האפליקציה כשהיא לא בשימוש"</string> + <string name="unused_apps_summary" msgid="8839466950318403115">"הסרת ההרשאות, מחיקה של הקבצים הזמניים, הפסקה של קבלת ההתראות"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"הסרת ההרשאות, מחיקה של הקבצים הזמניים, הפסקה של קבלת ההתראות והעברת האפליקציה לארכיון"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"כדי להגן על הנתונים שלך, אם האפליקציה הזו לא תהיה בשימוש במשך מספר חודשים, ההרשאות שניתנו לה יוסרו."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"כדי להגן על הנתונים שלך, אם האפליקציה לא תהיה בשימוש במשך מספר חודשים, ההרשאות הבאות יוסרו: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"כדי להגן על הנתונים שלך, הוסרו הרשאות מאפליקציות שלא השתמשת בהן במשך מספר חודשים."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"הרשאה לניהול כל הקבצים"</string> <string name="ask_header" msgid="2633816846459944376">"יש לשאול בכל פעם"</string> <string name="denied_header" msgid="903209608358177654">"אין הרשאה"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> ב-<xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"לצפייה באפליקציות נוספות שיכולות לגשת לכל הקבצים"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{יום אחד}one{# ימים}two{יומיים}other{# ימים}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{שעה}one{# שעות}two{שעתיים}other{# שעות}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"אפליקציית פתקים"</string> <string name="role_notes_description" msgid="8496852798616883551">"אפליקציות שמאפשרות לך לרשום הערות במכשיר"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"הערות"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ברירת המחדל של אפליקציית הארנק"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"אפליקציית ארנק"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"אפליקציות ארנק מאחסנות את כרטיסי האשראי ואת כרטיסי מועדון הלקוחות שלך, את מפתחות הרכב ועוד כדי לעזור בסוגים שונים של עסקאות."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"להגדיר את <xliff:g id="APP_NAME">%1$s</xliff:g> כברירת המחדל של אפליקציית הארנק?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"אין צורך בהרשאות"</string> <string name="request_role_current_default" msgid="738722892438247184">"ברירת המחדל הנוכחית"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"לא לשאול שוב"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"הגדרה כברירת מחדל"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"עדכונים לגבי שיתוף הנתונים"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"בחלק מהאפליקציות, השתנה האופן שבו הן עשויות לשתף את נתוני המיקום שלך"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"הגדרות"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"תאריך גישה: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"גישה אתמול: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"תאריך גישה: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> ב-<xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"הסיסמה החד-פעמית שלך היא 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"הגדרה מוגבלת"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"מטעמי אבטחה, ההגדרה הזו לא זמינה כרגע."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"בקשת הגישה של האפליקציה ל<xliff:g id="PERMISSION_NAME">%1$s</xliff:g> נדחתה"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"האפליקציה ביקשה הרשאת גישה למידע רגיש שעלולה לסכן את המידע האישי והפיננסי שלך.<xliff:g id="ID_1"><br><br></xliff:g>יכול להיות שהאפליקציה לא תעבוד כמו שצריך ללא ההרשאה המוגבלת הזו. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>מידע נוסף על מתן גישה להרשאות</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"בקשת הגישה של האפליקציה לשמש כברירת המחדל של <xliff:g id="ROLE_NAME">%1$s</xliff:g> נדחתה"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"האפליקציה ביקשה הרשאת גישה למידע רגיש שעלולה לסכן את המידע האישי והפיננסי שלך.<xliff:g id="ID_1"><br><br></xliff:g>יכול להיות שהאפליקציה לא תעבוד כמו שצריך ללא ההרשאות המוגבלות האלו. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>מידע נוסף על מתן גישה להרשאות</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"בקשת הגישה של האפליקציה נדחתה"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"מתן גישה להרשאה הזו עלול לסכן את המידע האישי והפיננסי שלך.<xliff:g id="ID_1"><br><br></xliff:g>יכול להיות שהאפליקציה לא תעבוד כמו שצריך ללא ההרשאה המוגבלת הזו. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>מידע נוסף על מתן גישה להרשאות</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"מידע נוסף"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"הבנתי"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"בקשת ההרשאה בוטלה"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"האפליקציה הזו מבקשת הרשאות נוספות, אבל אי אפשר לתת הרשאות בזמן פעילות של סטרימינג. צריך לתת את ההרשאה קודם בטלפון."</string> </resources> diff --git a/PermissionController/res/values-ja-v34/strings.xml b/PermissionController/res/values-ja-v34/strings.xml index 1a27a1df1..bf8c8edf4 100644 --- a/PermissionController/res/values-ja-v34/strings.xml +++ b/PermissionController/res/values-ja-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"健康に関するデータへのアプリのアクセス権を管理します"</string> <string name="location_settings" msgid="8863940440881290182">"位置情報へのアクセス"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"アプリとサービスによるアクセス。この設定が OFF の場合でも、緊急通報番号に発信したときは、マイクのデータが共有されることがあります"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"アプリとサービスによるアクセス"</string> </resources> diff --git a/PermissionController/res/values-ja-watch/strings.xml b/PermissionController/res/values-ja-watch/strings.xml index f47df141c..edd0d5c64 100644 --- a/PermissionController/res/values-ja-watch/strings.xml +++ b/PermissionController/res/values-ja-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"変更不可"</string> <string name="generic_yes" msgid="2489207724988649846">"はい"</string> <string name="generic_cancel" msgid="2631708607129269698">"キャンセル"</string> + <string name="permission_access_always" msgid="2107115233573823032">"常時"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"アプリの使用中"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"常時"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"アプリの使用中"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"常時"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"アプリの使用中"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"常時"</string> </resources> diff --git a/PermissionController/res/values-ja/strings.xml b/PermissionController/res/values-ja/strings.xml index b861cbf0d..5dab7c157 100644 --- a/PermissionController/res/values-ja/strings.xml +++ b/PermissionController/res/values-ja/strings.xml @@ -34,7 +34,7 @@ <string name="grant_dialog_button_more_info" msgid="213350268561945193">"詳細"</string> <string name="grant_dialog_button_allow_all" msgid="5939066403732409516">"すべて許可"</string> <string name="grant_dialog_button_always_allow_all" msgid="1719900027660252167">"常にすべて許可"</string> - <string name="grant_dialog_button_allow_limited_access" msgid="5713551784422137594">"アクセス制限を許可する"</string> + <string name="grant_dialog_button_allow_limited_access" msgid="5713551784422137594">"制限付きでアクセスを許可する"</string> <string name="grant_dialog_button_allow_selected_photos" msgid="5497042471576153842">"写真と動画を選択"</string> <string name="grant_dialog_button_allow_more_selected_photos" msgid="5145657877588697709">"さらに選択"</string> <string name="grant_dialog_button_dont_select_more" msgid="6643552729129461268">"他を選択しない"</string> @@ -56,8 +56,8 @@ <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"おおよその位置情報を保持"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"今回のみ"</string> <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"常に許可"</string> - <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"すべてのファイルの管理を許可"</string> - <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"メディア ファイルへのアクセスを許可"</string> + <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"すべての管理を許可"</string> + <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"アクセスのみ許可"</string> <string name="app_permissions_breadcrumb" msgid="5136969550489411650">"アプリ"</string> <string name="app_permissions" msgid="3369917736607944781">"アプリの権限"</string> <string name="unused_apps" msgid="2058057455175955094">"使用されていないアプリ"</string> @@ -86,7 +86,7 @@ <string name="app_permissions_group_summary" msgid="8788419008958284002">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> 個のアプリを許可"</string> <string name="app_permissions_group_summary2" msgid="4329922444840521150">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> 件のアプリを許可"</string> <string name="menu_show_system" msgid="4254021607027872504">"システムアプリを表示"</string> - <string name="menu_hide_system" msgid="3855390843744028465">"システムアプリを表示しない"</string> + <string name="menu_hide_system" msgid="3855390843744028465">"システムアプリを非表示"</string> <string name="menu_show_7_days_data" msgid="8979611198508523706">"過去 7 日間を表示"</string> <string name="menu_show_24_hours_data" msgid="8228054833323380780">"過去 24 時間を表示"</string> <string name="manage_permission" msgid="2895385393037061964">"権限の管理"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"すべての権限"</string> <string name="other_permissions" msgid="2901186127193849594">"その他のアプリ機能"</string> <string name="permission_request_title" msgid="8790310151025020126">"権限のリクエスト"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear ではインストールやアンインストールはできません。"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可する権限の選択"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> が更新されました。このアプリに許可する権限を選択してください。"</string> <string name="review_button_cancel" msgid="2191147944056548886">"キャンセル"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"正確な位置情報がオフの場合、アプリはおおよその位置情報にアクセスできます"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>の権限"</string> <string name="app_permission_header" msgid="2951363137032603806">"このアプリによる<xliff:g id="PERM">%1$s</xliff:g>へのアクセス"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> でこのアプリに <xliff:g id="PERM">%1$s</xliff:g> へのアクセス権が付与されています"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"「<xliff:g id="APP">%1$s</xliff:g>」アプリの権限をすべて表示"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"この権限があるアプリをすべて表示"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"アシスタントのマイクの使用を表示"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"アプリが使用されていない場合に権限を削除"</string> <string name="unused_apps_label" msgid="2595428768404901064">"権限を削除して空き容量を増やす"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"使用していないアプリを一時停止する"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"使用していないアプリを管理する"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"権限と一時ファイルを削除し、通知を停止します"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"権限と一時ファイルを削除し、通知を停止し、アプリをアーカイブします"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"データ保護のため、このアプリが数か月使用されていない場合はアプリの権限が取り消されます。"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"データ保護のため、アプリが数か月使用されていない場合は以下の権限が取り消されます。<xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"データ保護のため、数か月使用していないアプリの権限を削除しました。"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"すべてのファイルの管理が許可されたアプリ"</string> <string name="ask_header" msgid="2633816846459944376">"毎回確認する"</string> <string name="denied_header" msgid="903209608358177654">"許可しない"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>(<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"すべてのファイルにアクセスできるアプリをもっと見る"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 日}other{# 日}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# 時間}other{# 時間}}"</string> @@ -351,7 +353,7 @@ <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"これらのアプリでは、画面、アクション、入力の表示、アクションの実行、ディスプレイの操作を行えます。"</string> <string name="role_assistant_label" msgid="4727586018198208128">"デフォルトのデジタル アシスタント アプリ"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"デジタル アシスタント アプリ"</string> - <string name="role_assistant_description" msgid="6622458130459922952">"アシストアプリは、表示している画面の情報に基づいてアシスタントを提供します。一部のアプリはランチャーと音声入力サービスの両方に対応しており、統合されたアシスタントを提供します。"</string> + <string name="role_assistant_description" msgid="6622458130459922952">"アシストアプリは、表示している画面の情報に基づいてサポートを提供します。一部のアプリはランチャーと音声入力サービスの両方に対応しており、統合されたサポートを提供します。"</string> <string name="role_browser_label" msgid="2877796144554070207">"デフォルトのブラウザアプリ"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"ブラウザアプリ"</string> <string name="role_browser_description" msgid="3465253637499842671">"インターネットにアクセスするためのアプリです。タップしたリンクは、このアプリで開きます。"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"メモアプリ"</string> <string name="role_notes_description" msgid="8496852798616883551">"デバイスでメモの作成に使うアプリ"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"メモ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"デフォルトのウォレット アプリ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"ウォレット アプリ"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"ウォレット アプリにクレジット カード、ポイントカード、車のキーなどの情報を保存して、さまざまな取引に対応できます。"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> をデフォルトのウォレット アプリに設定しますか?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"権限は必要ありません"</string> <string name="request_role_current_default" msgid="738722892438247184">"現在のデフォルト"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"次回から表示しない"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"デフォルトに設定"</string> @@ -458,7 +465,7 @@ <string name="assistant_record_audio_user_sensitive_summary" msgid="6482937591816401619">"マイクを使って音声アシスタントを有効にする場合にステータスバーにアイコンを表示する"</string> <string name="permgrouprequest_storage_isolated" msgid="4892154224026852295">"デバイス内の写真やメディアへのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> <string name="permgrouprequest_device_aware_storage_isolated" msgid="5934218468708513375">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> 内の写真とメディアへのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> - <string name="permgrouprequest_contacts" msgid="8391550064551053695">"連絡先へのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> + <string name="permgrouprequest_contacts" msgid="8391550064551053695">"連絡先へのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> 内の連絡先へのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"このデバイスの位置情報へのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> の位置情報へのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"このアプリは、いつでも(ユーザーがアプリを使用していない場合でも)音声を録音できる権限を求めています。"<annotation id="link">"[設定] で許可してください。"</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"身体活動データへのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> 内の身体活動データへのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"写真と動画の撮影を「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"写真と動画の撮影を <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> での写真と動画の撮影を <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"アプリは、ユーザーがアプリを使用している場合のみ写真や動画を撮影できます"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"写真と動画の撮影を <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> @@ -512,9 +519,9 @@ <string name="permgroupupgraderequest_camera" msgid="640758449200241582">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に対するカメラへのアクセス許可を変更しますか?"</string> <string name="permgroupupgraderequest_device_aware_camera" msgid="4198765626608612156">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> のカメラに対する <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> のアクセス権を変更しますか?"</string> <string name="permgroupupgraderequestdetail_camera" msgid="6642747548010962597">"このアプリは、いつでも(ユーザーがアプリを使用していない場合でも)写真や動画を撮影できる権限を求めています。"<annotation id="link">"[設定] で許可してください。"</annotation></string> - <string name="permgrouprequest_calllog" msgid="2065327180175371397">"通話履歴へのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> + <string name="permgrouprequest_calllog" msgid="2065327180175371397">"通話履歴へのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> 内の通話履歴へのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> - <string name="permgrouprequest_phone" msgid="1829234136997316752">"電話の発信と管理を「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> + <string name="permgrouprequest_phone" msgid="1829234136997316752">"電話の発信と管理を <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_device_aware_phone" msgid="4389610977195521813">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> での電話の発信と管理を <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_sensors" msgid="4397358316850652235">"バイタルサインに関するセンサーデータへのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> <string name="permgrouprequest_device_aware_sensors" msgid="1900598688488188225">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b> 内のバイタルサインに関するセンサーデータへのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> @@ -612,7 +619,7 @@ <string name="mic_toggle_description" msgid="9163104307990677157">"アプリとサービスによるアクセス。この設定が OFF の場合でも、緊急通報番号に発信したときは、マイクのデータが共有されることがあります。"</string> <string name="location_settings_subtitle" msgid="2328360561197430695">"位置情報にアクセスできるアプリとサービスを確認"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"クリップボードへのアクセスを通知"</string> - <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"クリップボードにコピーしたテキストや画像などにアプリがアクセスすると、メッセージが表示されます"</string> + <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"クリップボードにコピーしたテキストや画像などにアプリがアクセスした際に、メッセージを表示します"</string> <string name="show_password_title" msgid="2877269286984684659">"パスワードを表示"</string> <string name="show_password_summary" msgid="1110166488865981610">"入力した文字を一瞬だけ表示します"</string> <string name="permission_rationale_message_location" msgid="2153841534298068414">"このアプリは、位置情報をサードパーティと共有する可能性があります"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"データ共有に関する更新"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"ユーザーの位置情報を共有する方法が変更されたアプリがあります"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"設定"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> にアクセス"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"昨日の <xliff:g id="TIME_DATE">%1$s</xliff:g> にアクセス"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g> にアクセス"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ワンタイム パスワードは 132435 です"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"制限付き設定"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"セキュリティ保護のため、この設定は現在利用できません。"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"アプリは<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>へのアクセスを拒否されました"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"機密情報に関わる権限へのアクセスをアプリがリクエストしました。この権限へのアクセスは、あなたの個人情報や財務情報を危険にさらす恐れがあります。<xliff:g id="ID_1"><br><br></xliff:g>この制限付きの権限がないとアプリは正しく動作しない可能性があります。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>アクセスを許可する方法の詳細</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"アプリはデフォルトの<xliff:g id="ROLE_NAME">%1$s</xliff:g>としてのアクセスを拒否されました"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"機密情報に関わる権限へのアクセスをアプリがリクエストしました。これらの権限へのアクセスは、あなたの個人情報や財務情報を危険にさらす恐れがあります。<xliff:g id="ID_1"><br><br></xliff:g>これらの制限付きの権限がないとアプリは正しく動作しない可能性があります。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>アクセスを許可する方法の詳細</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"アプリはアクセスを拒否されました"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"この権限へのアクセスは、あなたの個人情報や財務情報を危険にさらす恐れがあります。<xliff:g id="ID_1"><br><br></xliff:g>この制限付きの権限がないとアプリは正しく動作しない可能性があります。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>アクセスを許可する方法の詳細</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"詳細"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"権限のリクエストが抑制されています"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"このアプリは追加の権限を求めていますが、ストリーミング セッションでは権限を付与できません。スマートフォンで先に権限を付与してください。"</string> </resources> diff --git a/PermissionController/res/values-ka-v34/strings.xml b/PermissionController/res/values-ka-v34/strings.xml index c3e4c7715..e67e8ffa0 100644 --- a/PermissionController/res/values-ka-v34/strings.xml +++ b/PermissionController/res/values-ka-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ჯანმრთელობის მონაცემებზე აპის წვდომის მართვა"</string> <string name="location_settings" msgid="8863940440881290182">"მდებარეობაზე წვდომა"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"აპებისა და სერვისებისთვის. მიკროფონის მონაცემები, შესაძლოა, მაინც გაზიარდეს გადაუდებელი დახმარების სამსახურის ნომერზე დარეკვისას, როცა ეს პარამეტრი გამორთულია"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"აპებისა და სერვისებისთვის"</string> </resources> diff --git a/PermissionController/res/values-ka-watch/strings.xml b/PermissionController/res/values-ka-watch/strings.xml index f3ca03402..357e9cd00 100644 --- a/PermissionController/res/values-ka-watch/strings.xml +++ b/PermissionController/res/values-ka-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ვერ შეიცვლება"</string> <string name="generic_yes" msgid="2489207724988649846">"დიახ"</string> <string name="generic_cancel" msgid="2631708607129269698">"გაუქმება"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Მუდმივად"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"აპის გამოყენებისას"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Მუდმივად"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"აპის გამოყენებისას"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Მუდმივად"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"აპის გამოყენებისას"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Მუდმივად"</string> </resources> diff --git a/PermissionController/res/values-ka/strings.xml b/PermissionController/res/values-ka/strings.xml index b8bc6fd95..7eb3b5a1b 100644 --- a/PermissionController/res/values-ka/strings.xml +++ b/PermissionController/res/values-ka/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ყველა ნებართვა"</string> <string name="other_permissions" msgid="2901186127193849594">"აპის სხვა შესაძლებლობები"</string> <string name="permission_request_title" msgid="8790310151025020126">"ნებართვის მოთხოვნა"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"ინსტალაციის/დეინსტალაციის მოქმედებები არ არის მხარდაჭერილი Wear-ზე."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"აირჩიეთ, რაზე ჰქონდეს წვდომა <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-ს"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> განახლდა. აირჩიეთ, რაზე ჰქონდეს წვდომა ამ აპს."</string> <string name="review_button_cancel" msgid="2191147944056548886">"გაუქმება"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"როდესაც ზუსტი მდებარეობა გამორთულია, აპებს თქვენს მიახლოებით მდებარეობაზე წვდომა შეუძლია"</string> <string name="app_permission_title" msgid="2090897901051370711">"ნებართვა: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>-ზე წვდომა ამ აპისთვის"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"(<xliff:g id="PERM">%1$s</xliff:g>) წვდომა ამ აპისთვის <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ზე"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"ყველა ნებართვის ნახვა: <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ამ ნებართვის მქონე ყველა აპის ნახვა"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"ასისტენტის მიკროფონის გამოყენების ჩვენება"</string> - <string name="unused_apps_category_title" msgid="2988455616845243901">"აპის გამოუყენებელი პარამეტრები"</string> + <string name="unused_apps_category_title" msgid="2988455616845243901">"გამოუყენებელი აპის პარამეტრები"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"ნებართვების ამოშლა აპის გამოუყენებლობის შემთხვევაში."</string> <string name="unused_apps_label" msgid="2595428768404901064">"ნებართვების ამოშლა და მეხსიერების გათავისუფლება"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"დაპაუზდეს აპში აქტივობა, თუ არ იყენებენ"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"აპის მართვა გამოუყენებლობის შემთხვევაში"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ნებართვების ამოშლა, დროებითი ფაილების წაშლა და შეტყობინებების გამორთვა"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ნებართვების ამოშლა, დროებითი ფაილების წაშლა, შეტყობინებების გამორთვა და აპის დაარქივება"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"თქვენი მონაცემების დასაცავად ნებართვები ამოიშლება ამ აპიდან, თუ ის რამდენიმე თვის განმავლობაში არ გამოგიყენებიათ."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"თქვენი მონაცემების დაცვის მიზნით, თუ აპს რამდენიმე თვის განმავლობაში არ გამოიყენებთ, ამოიშლება შემდეგი ნებართვები: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"თქვენი მონაცემების დასაცავად ნებართვები ამოიშალა აპებიდან, რომლებიც რამდენიმე თვის განმავლობაში არ გამოგიყენებიათ."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"დაშვებულია ყველა ფაილის მართვა"</string> <string name="ask_header" msgid="2633816846459944376">"ყოველთვის მკითხე"</string> <string name="denied_header" msgid="903209608358177654">"არ არის დაშვებული"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"სხვა აპების ნახვა, რომლებსაც ყველა ფაილზე წვდომა შეუძლია"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 დღე}other{# დღე}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# საათი}other{# საათი}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"ჩანიშვნების აპი"</string> <string name="role_notes_description" msgid="8496852798616883551">"აპები, რომლებიც საშუალებას გაძლევთ, გააკეთოთ ჩანიშვნები თქვენს მოწყობილობაზე"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ჩანიშვნები"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ნაგულისხმევი საფულის აპი"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"საფულის აპი"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"საფულის აპებს შეუძლიათ საკრედიტო და ერთგული კლიენტის ბარათების, მანქანის გასაღებების და სხვა ნივთების შენახვა, რაც დაგეხმარებათ სხვადასხვა სახის ტრანზაქციებში."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"გსურთ დააყენოთ <xliff:g id="APP_NAME">%1$s</xliff:g> თქვენს ნაგულისხმევ საფულის აპად?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ნებართვები არ არის საჭირო"</string> <string name="request_role_current_default" msgid="738722892438247184">"ამჟამინდელი ნაგულისხმევი"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"აღარ მკითხოთ"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ნაგულისხმ. დაყენება"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"მონაცემთა გაზიარების განახლება"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"ზოგიერთმა აპმა შეცვალა თქვენი მდებარეობის მონაც. გაზიარების გზები"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"პარამეტრები"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"წვდომა განხორციელდა: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"წვდომა განხორციელდა გუშინ: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"წვდომა განხორციელდა: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"თქვენი ერთჯერადი პაროლია: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"შეზღუდული პარამეტრი"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"თქვენივე უსაფრთხოებისთვის ეს პარამეტრი ამჟამად მიუწვდომელია."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"აპისთვის უარყოფილია ნებართვაზე წვდომა: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"აპმა სენსიტიურ ინფორმაციაზე წვდომა მოითხოვა, რაც თქვენს პირად და ფინანსურ ინფორმაციას საფრთხის ქვეშ აყენებს.<xliff:g id="ID_1"><br><br></xliff:g>შესაძლოა აპმა ამ შეზღუდული ნებართვის გარეშე სათანადოდ ვერ იმუშაოს. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>შეიტყვეთ მეტი ნებართვის დაშვების შესახებ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"აპისთვის ნაგულისხმევ როლზე (<xliff:g id="ROLE_NAME">%1$s</xliff:g>) წვდომა უარყოფილია"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"აპმა სენსიტიურ ინფორმაციაზე წვდომა მოითხოვა, რაც თქვენს პირად და ფინანსურ ინფორმაციას საფრთხის ქვეშ აყენებს.<xliff:g id="ID_1"><br><br></xliff:g>შესაძლოა აპმა ამ შეზღუდული ნებართვის გარეშე სათანადოდ ვერ იმუშაოს. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>შეიტყვეთ მეტი ნებართვის დაშვების შესახებ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"აპისთვის წვდომა უარყოფილია"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ამ ნებართვაზე წვდომა თქვენს პირად და ფინანსურ ინფორმაციას საფრთხის ქვეშ აყენებს.<xliff:g id="ID_1"><br><br></xliff:g>შესაძლოა აპმა ამ შეზღუდული ნებართვის გარეშე სათანადოდ ვერ იმუშაოს. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>შეიტყვეთ მეტი ნებართვის დაშვების შესახებ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"შეიტყვეთ მეტი"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"კარგი"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"ნებართვის მოთხოვნა შეჩერებულია"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ეს აპი დამატებით ნებართვებს მოითხოვს, მაგრამ ნებართვების მიცემა შეუძლებელია სტრიმინგის სესიაში. თავდაპირველად მიანიჭეთ ნებართვა ტელეფონზე."</string> </resources> diff --git a/PermissionController/res/values-kk-v34/strings.xml b/PermissionController/res/values-kk-v34/strings.xml index 002624b5a..0e992048f 100644 --- a/PermissionController/res/values-kk-v34/strings.xml +++ b/PermissionController/res/values-kk-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Қолданбаның денсаулық деректерін пайдалану рұқсатын басқару"</string> <string name="location_settings" msgid="8863940440881290182">"Локацияны пайдалану рұқсаты"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Қолданбалар мен қызметтерге арналған. Бұл параметр өшірілсе де, құтқару қызметінің нөміріне қоңырау шалғанда, микрофон деректері жіберілуі мүмкін."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Қолданбалар мен қызметтерге арналған."</string> </resources> diff --git a/PermissionController/res/values-kk-watch/strings.xml b/PermissionController/res/values-kk-watch/strings.xml index 1adaab343..8cbb401c4 100644 --- a/PermissionController/res/values-kk-watch/strings.xml +++ b/PermissionController/res/values-kk-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Өзгерту мүмкін емес"</string> <string name="generic_yes" msgid="2489207724988649846">"Иә"</string> <string name="generic_cancel" msgid="2631708607129269698">"Бас тарту"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Әрдайым"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Қолданбаны пайдаланғанда"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Әрдайым"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Қолданбаны пайдаланғанда"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Әрдайым"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Қолданбаны пайдаланғанда"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Әрдайым"</string> </resources> diff --git a/PermissionController/res/values-kk/strings.xml b/PermissionController/res/values-kk/strings.xml index b39b229c3..3d8d66465 100644 --- a/PermissionController/res/values-kk/strings.xml +++ b/PermissionController/res/values-kk/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Барлық рұқсаттар"</string> <string name="other_permissions" msgid="2901186127193849594">"Басқа қолданба мүмкіндіктері"</string> <string name="permission_request_title" msgid="8790310151025020126">"Рұқсат сұрау"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear жүйесінде \"Орнату\"/\"Жою\" әрекеттері қолданылмайды."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасы қайда кіре алатынын таңдаңыз"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасы жаңартылды. Бұл қолданбаның қайда кіре алатынын таңдаңыз."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Бас тарту"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Нақты локацияңыз өшірулі болған кезде, қолданбалар болжалды локацияңызды пайдалана алады."</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> рұқсаты"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: осы қолданбаның рұқсаты"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Құрылғыдағы (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) осы қолданбаның рұқсаты: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Барлық <xliff:g id="APP">%1$s</xliff:g> рұқсаттарын көру"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Осы рұқсатқа ие барлық қолданбаларды көру"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistant микрофонының пайдаланылуын көрсету"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Қолданба пайдаланылмаса, рұқсаттарды өшіру"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Рұқсаттарды өшіру және орын босату"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Әрекетсіз қолданба жұмысын кідірту"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Пайдаланылмайтын қолданбалардың жұмысын кідірту"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Рұқсаттарды өшіру, уақытша файлдарды жою және хабарландыруларды тоқтату"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Рұқсаттарды өшіру, уақытша файлдарды жою, хабарландыруларды тоқтату және қолданбаны мұрағаттау"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Бұл қолданба бірнеше ай бойы пайдаланылмаса, деректеріңізді қорғау үшін оған берілген рұқсаттар өшіріледі."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Қолданба бірнеше ай бойы пайдаланылмаса, деректеріңізді қорғау үшін мына рұқсаттар өшіріледі: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Бірнеше ай бойы пайдаланылмаған қолданбаларға берілген рұқсаттар деректеріңізді қорғау үшін өшірілді."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Барлық файлдарды басқара алатын қолданбалар"</string> <string name="ask_header" msgid="2633816846459944376">"Әрдайым сұрау"</string> <string name="denied_header" msgid="903209608358177654">"Рұқсат берілмегендер"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Барлық файлды пайдалана алатын тағы басқа қолданбаларды көру"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 күн}other{# күн}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# сағат}other{# сағат}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Ескертпелер қолданбасы"</string> <string name="role_notes_description" msgid="8496852798616883551">"Құрылғыда ескертпелер жазуға арналған қолданбалар"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ескертпелер"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Әдепкі әмиян қолданбасы"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Әмиян қолданбасы"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Әмиян қолданбаларында несиелік және тұрақты клиент карталарын, көлік кілттерін, сондай-ақ басқа да транзакция түрлері үшін қолайлы заттарды сақтауға болады."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын әдепкі әмиян қолданбасы ретінде орнату керек пе?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Рұқсаттар қажет емес."</string> <string name="request_role_current_default" msgid="738722892438247184">"Ағымдағы әдепкі қолданба"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Қайта сұралмасын"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Әдепкі етіп орнату"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына контактілерді пайдалануға рұқсат берілсін бе?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына <b><xliff:g id="DEVICE">%2$s</xliff:g></b> құрылғысында контактілерді пайдалану рұқсаты берілсін бе?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына осы құрылғының локациясын пайдалануға рұқсат берілсін бе?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b> құрылғысының локациясын пайдалану рұқсаты берілсін бе?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> құрылғысының локациясын пайдалану рұқсаты берілсін бе?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Қолданбаны пайдалану кезінде ғана оған геодеректеріңізді көруге рұқсат етіледі."</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына осы құрылғының локациясын пайдалануға рұқсат берілсін бе?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g> құрылғысының локациясын пайдалану рұқсаты берілсін бе?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Деректерді бөлісуге қатысты жаңалық"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Кейбір қолданбалар локация деректеріңізді бөлісу жолын өзгертті."</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Параметрлер"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Пайдаланылған уақыты: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Кеше пайдаланылған уақыты: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Пайдаланылған уақыты: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Бір реттік құпия сөзіңіз: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Шектелген параметр"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Қауіпсіздік мақсатында бұл параметрді қазір пайдалану мүмкін емес."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Қолданбаға <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> рұқсаты берілмеді"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Қолданба жеке және қаржылық ақпаратыңызға қауіп төндіруі мүмкін құпия ақпарат рұқсатын сұрады.<xliff:g id="ID_1"><br><br></xliff:g>Қолданба бұл шектеулі рұқсатсыз дұрыс жұмыс істемеуі мүмкін. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Рұқсат беру туралы ақпарат</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Қолданбаға әдепкі <xliff:g id="ROLE_NAME">%1$s</xliff:g> болу рұқсаты берілмеді"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Қолданба жеке және қаржылық ақпаратыңызға қауіп төндіруі мүмкін құпия ақпарат рұқсаттарын сұрады.<xliff:g id="ID_1"><br><br></xliff:g>Қолданба бұл шектеулі рұқсаттарсыз дұрыс жұмыс істемеуі мүмкін. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Рұқсат беру туралы ақпарат</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Қолданбаға рұқсат берілмеді"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Бұл рұқсатты берсеңіз, жеке және қаржылық ақпаратыңызға қауіп төнуі мүмкін.<xliff:g id="ID_1"><br><br></xliff:g>Қолданба бұл шектеулі рұқсатсыз дұрыс жұмыс істемеуі мүмкін. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Рұқсат беру туралы ақпарат</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Толық ақпарат"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Жарайды"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Рұқсат сұрауы блокталды"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Бұл қолданба қосымша рұқсаттар сұрап жатыр, бірақ трансляция жүріп жатқанда рұқсат беру мүмкін емес. Алдымен телефонда рұқсат беріңіз."</string> </resources> diff --git a/PermissionController/res/values-km-v34/strings.xml b/PermissionController/res/values-km-v34/strings.xml index ccf92d186..95bf039cd 100644 --- a/PermissionController/res/values-km-v34/strings.xml +++ b/PermissionController/res/values-km-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"គ្រប់គ្រងសិទ្ធិរបស់កម្មវិធីក្នុងការចូលប្រើទិន្នន័យសុខភាព"</string> <string name="location_settings" msgid="8863940440881290182">"ការចូលប្រើប្រាស់ទីតាំង"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"សម្រាប់កម្មវិធី និងសេវាកម្ម។ ប្រសិនបើការកំណត់នេះត្រូវបានបិទ ទិន្នន័យមីក្រូហ្វូននៅតែអាចត្រូវបានចែករំលែកដដែល នៅពេលអ្នកហៅទៅលេខសង្គ្រោះបន្ទាន់"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"សម្រាប់កម្មវិធី និងសេវាកម្ម"</string> </resources> diff --git a/PermissionController/res/values-km-watch/strings.xml b/PermissionController/res/values-km-watch/strings.xml index de12569e2..08504f8f1 100644 --- a/PermissionController/res/values-km-watch/strings.xml +++ b/PermissionController/res/values-km-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"មិនអាចប្តូរបានទេ"</string> <string name="generic_yes" msgid="2489207724988649846">"បាទ/ចាស"</string> <string name="generic_cancel" msgid="2631708607129269698">"បោះបង់"</string> + <string name="permission_access_always" msgid="2107115233573823032">"គ្រប់ពេល"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ពេលកំពុងប្រើកម្មវិធី"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"គ្រប់ពេល"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ពេលកំពុងប្រើកម្មវិធី"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"គ្រប់ពេល"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ពេលកំពុងប្រើកម្មវិធី"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"គ្រប់ពេល"</string> </resources> diff --git a/PermissionController/res/values-km/strings.xml b/PermissionController/res/values-km/strings.xml index d1b60ad11..6a3db0455 100644 --- a/PermissionController/res/values-km/strings.xml +++ b/PermissionController/res/values-km/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ការអនុញ្ញាតទាំងអស់"</string> <string name="other_permissions" msgid="2901186127193849594">"សមត្ថភាពកម្មវិធីផ្សេងទៀត"</string> <string name="permission_request_title" msgid="8790310151025020126">"សំណើសុំការអនុញ្ញាត"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"សកម្មភាពដំឡើង/លុបចេញមិនអាចប្រើនៅលើ Wear បានទេ។"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"ជ្រើសរើសអ្វីដែលត្រូវអនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើ"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ត្រូវបានដំឡើងជំនាន់។ ជ្រើសរើសអ្វីដែលត្រូវអនុញ្ញាតឱ្យកម្មវិធីនេះចូលប្រើ។"</string> <string name="review_button_cancel" msgid="2191147944056548886">"បោះបង់"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"នៅពេលបិទទីតាំងជាក់លាក់ កម្មវិធីអាចចូលប្រើទីតាំងប្រហាក់ប្រហែលរបស់អ្នក"</string> <string name="app_permission_title" msgid="2090897901051370711">"ការអនុញ្ញាត<xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"ការចូលប្រើ<xliff:g id="PERM">%1$s</xliff:g>សម្រាប់កម្មវិធីនេះ"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"សិទ្ធិចូលប្រើ <xliff:g id="PERM">%1$s</xliff:g> សម្រាប់កម្មវិធីនេះនៅលើ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"មើលការអនុញ្ញាតទាំងអស់ឱ្យទៅ <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"មើលកម្មវិធីទាំងអស់ដែលមានការអនុញ្ញាតនេះ"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"បង្ហាញការប្រើប្រាស់មីក្រូហ្វូនរបស់ជំនួយការ"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ដកការអនុញ្ញាតចេញ ប្រសិនបើមិនប្រើប្រាស់កម្មវិធី"</string> <string name="unused_apps_label" msgid="2595428768404901064">"ដកការអនុញ្ញាតចេញ និងបង្កើនទំហំផ្ទុក"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"ផ្អាកសកម្មភាពកម្មវិធី ប្រសិនបើមិនប្រើ"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"គ្រប់គ្រងកម្មវិធី ប្រសិនបើមិនបានប្រើ"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ដកការអនុញ្ញាតចេញ លុបឯកសារបណ្ដោះអាសន្ន និងបញ្ឈប់ការជូនដំណឹង"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ដកការអនុញ្ញាតចេញ លុបឯកសារបណ្ដោះអាសន្ន បញ្ឈប់ការជូនដំណឹង និងទុកកម្មវិធីក្នុងបណ្ណសារ"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"ដើម្បីការពារទិន្នន័យរបស់អ្នក ការអនុញ្ញាតសម្រាប់កម្មវិធីនេះនឹងត្រូវដកចេញ ប្រសិនបើមិនប្រើប្រាស់កម្មវិធីនេះរយៈពេលពីរបីខែ។"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"ដើម្បីការពារទិន្នន័យរបស់អ្នក ការអនុញ្ញាតខាងក្រោមនឹងត្រូវដកចេញ ប្រសិនបើមិនប្រើប្រាស់កម្មវិធីនេះរយៈពេលពីរបីខែ៖ <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"ដើម្បីការពារទិន្នន័យរបស់អ្នក ការអនុញ្ញាតត្រូវបានដកចេញពីកម្មវិធីដែលអ្នកមិនបានប្រើប្រាស់រយៈពេលពីរបីខែ។"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"បានអនុញ្ញាតឱ្យគ្រប់គ្រងឯកសារទាំងអស់"</string> <string name="ask_header" msgid="2633816846459944376">"សួរគ្រប់ពេល"</string> <string name="denied_header" msgid="903209608358177654">"មិនបានអនុញ្ញាត"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> នៅលើ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"មើលកម្មវិធីច្រើនទៀតដែលអាចចូលប្រើឯកសារទាំងអស់បាន"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ថ្ងៃ}other{# ថ្ងៃ}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ម៉ោង}other{# ម៉ោង}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"កម្មវិធីកំណត់ចំណាំ"</string> <string name="role_notes_description" msgid="8496852798616883551">"កម្មវិធីដែលអនុញ្ញាតឱ្យអ្នកកត់ចំណាំនៅលើឧបករណ៍របស់អ្នក"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"កំណត់ចំណាំ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"កម្មវិធីកាបូបលំនាំដើម"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"កម្មវិធីកាបូប"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"កម្មវិធីកាបូបអាចរក្សាទុកកាតឥណទាននិងកាតសមាជិក សោរថយន្ត និងអ្វីៗផ្សេងទៀតរបស់អ្នក ដើម្បីជួយពាក់ព័ន្ធនឹងទម្រង់ផ្សេងៗរបស់ប្រតិបត្តិការ។"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"កំណត់ <xliff:g id="APP_NAME">%1$s</xliff:g> ជាកម្មវិធីកាបូបលំនាំដើមរបស់អ្នកឬ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"មិនត្រូវការការអនុញ្ញាតទេ"</string> <string name="request_role_current_default" msgid="738722892438247184">"លំនាំដើមបច្ចុប្បន្ន"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"កុំសួរទៀត"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"កំណត់ជាលំនាំដើម"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើទំនាក់ទំនងរបស់អ្នក?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើទំនាក់ទំនងរបស់អ្នកនៅលើ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> របស់អ្នកឬ?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើទីតាំងរបស់ឧបករណ៍នេះដែរទេ?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើទីតាំងនៃ <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b> របស់អ្នកឬ?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើទីតាំងនៃ <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> របស់អ្នកឬ?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"កម្មវិធីនេះនឹងមានសិទ្ធិចូលប្រើទីតាំង នៅពេលអ្នកកំពុងប្រើកម្មវិធីនេះតែប៉ុណ្ណោះ"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើទីតាំងរបស់ឧបករណ៍នេះដែរទេ?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលប្រើទីតាំង <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g> របស់អ្នកឬ?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"បច្ចុប្បន្នភាពការចែករំលែកទិន្នន័យ"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"កម្មវិធីមួយចំនួនបានផ្លាស់ប្ដូររបៀបដែលវាអាចចែករំលែកទិន្នន័យទីតាំងរបស់អ្នក"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ការកំណត់"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"បានចូលប្រើនៅម៉ោង <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"បានចូលប្រើម្សិលមិញនៅម៉ោង <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"បានចូលប្រើនៅថ្ងៃទី <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ពាក្យសម្ងាត់ប្រើបានតែម្ដងរបស់អ្នកគឺ 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"ការកំណត់ដែលបានដាក់កំហិត"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"ដើម្បីសុវត្ថិភាពរបស់អ្នក បច្ចុប្បន្នមិនអាចប្រើការកំណត់នេះបានទេ។"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"កម្មវិធីត្រូវបានបដិសេធមិនឱ្យចូលប្រើ<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"កម្មវិធីបានស្នើសុំសិទ្ធិចូលប្រើការអនុញ្ញាតដែលមានលក្ខណៈរសើប ដែលអាចធ្វើឱ្យព័ត៌មានហិរញ្ញវត្ថុ និងព័ត៌មានផ្ទាល់ខ្លួនរបស់អ្នកប្រឈមនឹងហានិភ័យ។<xliff:g id="ID_1"><br><br></xliff:g>កម្មវិធីអាចនឹងមិនដំណើរការបានត្រឹមត្រូវទេ ប្រសិនបើគ្មានការអនុញ្ញាតដែលមានការរឹតបន្តឹងនេះ។ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ស្វែងយល់អំពីរបៀបផ្ដល់សិទ្ធិចូលប្រើ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"កម្មវិធីត្រូវបានបដិសេធមិនឱ្យចូលប្រើជា<xliff:g id="ROLE_NAME">%1$s</xliff:g>លំនាំដើម"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"កម្មវិធីបានស្នើសុំសិទ្ធិចូលប្រើការអនុញ្ញាតដែលមានលក្ខណៈរសើប ដែលអាចធ្វើឱ្យព័ត៌មានហិរញ្ញវត្ថុ និងព័ត៌មានផ្ទាល់ខ្លួនរបស់អ្នកប្រឈមនឹងហានិភ័យ។<xliff:g id="ID_1"><br><br></xliff:g>កម្មវិធីអាចនឹងមិនដំណើរការបានត្រឹមត្រូវទេ ប្រសិនបើគ្មានការអនុញ្ញាតដែលមានការរឹតបន្តឹងទាំងនេះ។ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ស្វែងយល់អំពីរបៀបផ្ដល់សិទ្ធិចូលប្រើ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"កម្មវិធីត្រូវបានបដិសេធមិនឱ្យចូលប្រើ"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"សិទ្ធិចូលប្រើការអនុញ្ញាតនេះអាចនាំឱ្យព័ត៌មានផ្ទាល់ខ្លួន និងព័ត៌មានហិរញ្ញវត្ថុរបស់អ្នកប្រឈមនឹងហានិភ័យ។<xliff:g id="ID_1"><br><br></xliff:g>កម្មវិធីអាចនឹងមិនដំណើរការបានត្រឹមត្រូវទេ ប្រសិនបើគ្មានការអនុញ្ញាតដែលមានការរឹតបន្តឹងនេះ។ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ស្វែងយល់អំពីរបៀបផ្ដល់សិទ្ធិចូលប្រើ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ស្វែងយល់បន្ថែម"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"យល់ព្រម"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"បានទប់ស្កាត់សំណើសុំការអនុញ្ញាត"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"កម្មវិធីនេះកំពុងស្នើសុំការអនុញ្ញាតបន្ថែម ប៉ុន្តែមិនអាចផ្តល់ការអនុញ្ញាតក្នុងវគ្គផ្សាយបានទេ។ ផ្តល់ការអនុញ្ញាតនៅលើទូរសព្ទរបស់អ្នកជាមុនសិន។"</string> </resources> diff --git a/PermissionController/res/values-kn-v34/strings.xml b/PermissionController/res/values-kn-v34/strings.xml index 34a939459..0e0a442d9 100644 --- a/PermissionController/res/values-kn-v34/strings.xml +++ b/PermissionController/res/values-kn-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ಆರೋಗ್ಯದ ಡೇಟಾಕ್ಕೆ ಸಂಬಂಧಿಸಿದಂತೆ ಆ್ಯಪ್ನ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ನಿರ್ವಹಿಸಿ"</string> <string name="location_settings" msgid="8863940440881290182">"ಸ್ಥಳದ ಆ್ಯಕ್ಸೆಸ್"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ಆ್ಯಪ್ಗಳು ಮತ್ತು ಸೇವೆಗಳಿಗಾಗಿ. ಈ ಸೆಟ್ಟಿಂಗ್ ಆಫ್ ಆಗಿದ್ದಾಗಲೂ, ನೀವು ತುರ್ತು ಸಂಖ್ಯೆಯೊಂದಕ್ಕೆ ಕರೆ ಮಾಡಿದಾಗ ಮೈಕ್ರೊಫೋನ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ಆ್ಯಪ್ಗಳು ಮತ್ತು ಸೇವೆಗಳಿಗಾಗಿ"</string> </resources> diff --git a/PermissionController/res/values-kn-watch/strings.xml b/PermissionController/res/values-kn-watch/strings.xml index a05c39b72..1aae70857 100644 --- a/PermissionController/res/values-kn-watch/strings.xml +++ b/PermissionController/res/values-kn-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ಬದಲಿಸಲಾಗುವುದಿಲ್ಲ"</string> <string name="generic_yes" msgid="2489207724988649846">"ಹೌದು"</string> <string name="generic_cancel" msgid="2631708607129269698">"ರದ್ದುಮಾಡಿ"</string> + <string name="permission_access_always" msgid="2107115233573823032">"ಯಾವಾಗಲೂ"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ಆ್ಯಪ್ ಬಳಸುವಾಗ"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"ಯಾವಾಗಲೂ"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ಆ್ಯಪ್ ಬಳಸುವಾಗ"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"ಯಾವಾಗಲೂ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ಆ್ಯಪ್ ಬಳಸುವಾಗ"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"ಯಾವಾಗಲೂ"</string> </resources> diff --git a/PermissionController/res/values-kn/strings.xml b/PermissionController/res/values-kn/strings.xml index 547116264..5f5e3f48c 100644 --- a/PermissionController/res/values-kn/strings.xml +++ b/PermissionController/res/values-kn/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ಎಲ್ಲಾ ಅನುಮತಿಗಳು"</string> <string name="other_permissions" msgid="2901186127193849594">"ಇತರ ಆ್ಯಪ್ ಸಾಮರ್ಥ್ಯಗಳು"</string> <string name="permission_request_title" msgid="8790310151025020126">"ಅನುಮತಿಯ ವಿನಂತಿ"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear ನಲ್ಲಿ ಇನ್ಸ್ಟಾಲ್/ಅನ್ಇನ್ಸ್ಟಾಲ್ ಕ್ರಿಯೆಗಳು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಆ್ಯಪ್ಗೆ ಪ್ರವೇಶಿಸಲು ಯಾವುದನ್ನು ಅನುಮತಿಸಬೇಕು ಎಂಬುದನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಆ್ಯಪ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ಈ ಆ್ಯಪ್ಗೆ ಪ್ರವೇಶಿಸಲು ಯಾವುದನ್ನು ಅನುಮತಿಸಬೇಕು ಎಂಬುದನ್ನು ಆಯ್ಕೆಮಾಡಿ."</string> <string name="review_button_cancel" msgid="2191147944056548886">"ರದ್ದುಮಾಡಿ"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"ನಿಖರವಾದ ಸ್ಥಳ ಆಫ್ ಆಗಿರುವಾಗ, ಆ್ಯಪ್ಗಳು ನಿಮ್ಮ ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> ಅನುಮತಿ"</string> <string name="app_permission_header" msgid="2951363137032603806">"ಈ ಆ್ಯಪ್ಗಾಗಿ <xliff:g id="PERM">%1$s</xliff:g> ಆ್ಯಕ್ಸೆಸ್"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> ನಲ್ಲಿ ಈ ಆ್ಯಪ್ಗಾಗಿ <xliff:g id="PERM">%1$s</xliff:g> ಆ್ಯಕ್ಸೆಸ್"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"ಎಲ್ಲಾ <xliff:g id="APP">%1$s</xliff:g> ಅನುಮತಿಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ಈ ಅನುಮತಿಯನ್ನು ಹೊಂದಿರುವ ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"ಅಸಿಸ್ಟೆಂಟ್ನ ಮೈಕ್ರೋಫೋನ್ ಬಳಕೆಯನ್ನು ತೋರಿಸಿ"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ಆ್ಯಪ್ ಬಳಸದಿದ್ದರೆ ಅನುಮತಿಗಳನ್ನು ತೆಗೆದುಹಾಕಿ"</string> <string name="unused_apps_label" msgid="2595428768404901064">"ಅನುಮತಿಗಳನ್ನು ತೆಗೆಯಿರಿ, ಸ್ಥಳ ಮುಕ್ತಗೊಳಿಸಿ"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"ಬಳಸದಿದ್ದರೆ, ಆ್ಯಪ್ನ ಚಟುವಟಿಕೆಯನ್ನು ವಿರಾಮಗೊಳಿಸಿ"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ಬಳಸದಿದ್ದರೆ ಆ್ಯಪ್ ಅನ್ನು ನಿರ್ವಹಿಸಿ"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ಅನುಮತಿಗಳನ್ನು ತೆಗೆದುಹಾಕಿ, ತಾತ್ಕಾಲಿಕ ಫೈಲ್ಗಳನ್ನು ಅಳಿಸಿ ಹಾಗೂ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿಲ್ಲಿಸಿ"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ಅನುಮತಿಗಳನ್ನು ತೆಗೆದುಹಾಕಿ, ತಾತ್ಕಾಲಿಕ ಫೈಲ್ಗಳನ್ನು ಅಳಿಸಿ, ನೋಟಿಫಿಕೇಶನ್ಗಳನ್ನು ನಿಲ್ಲಿಸಿ ಮತ್ತು ಆ್ಯಪ್ ಅನ್ನು ಆರ್ಕೈವ್ ಮಾಡಿ"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"ಆ್ಯಪ್ ಅನ್ನು ಕೆಲವು ತಿಂಗಳುಗಳ ಕಾಲ ಬಳಸದಿದ್ದರೆ, ನಿಮ್ಮ ಡೇಟಾವನ್ನು ರಕ್ಷಿಸಲು ಈ ಆ್ಯಪ್ನ ಅನುಮತಿಗಳನ್ನು ತೆಗೆದುಹಾಕಲಾಗುವುದು."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"ಆ್ಯಪ್ ಅನ್ನು ಕೆಲವು ತಿಂಗಳುಗಳ ಕಾಲ ಬಳಸದಿದ್ದರೆ, ನಿಮ್ಮ ಡೇಟಾವನ್ನು ರಕ್ಷಿಸಲು, ಈ ಕೆಳಗಿನ ಅನುಮತಿಗಳನ್ನು ತೆಗೆದುಹಾಕಲಾಗುವುದು: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"ನಿಮ್ಮ ಡೇಟಾವನ್ನು ರಕ್ಷಿಸಲು, ಕೆಲವು ತಿಂಗಳುಗಳಿಂದ ನೀವು ಬಳಸದಿರುವ ಆ್ಯಪ್ಗಳಿಂದ ಅನುಮತಿಗಳನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ಎಲ್ಲಾ ಫೈಲ್ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಅನುಮತಿಸಲಾಗಿದೆ"</string> <string name="ask_header" msgid="2633816846459944376">"ಪ್ರತಿ ಬಾರಿ ಕೇಳಿ"</string> <string name="denied_header" msgid="903209608358177654">"ಅನುಮತಿಸಿಲ್ಲದಿರುವುದು"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> ನಲ್ಲಿನ <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ಎಲ್ಲಾ ಫೈಲ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಬಹುದಾದ ಇನ್ನಷ್ಟು ಆ್ಯಪ್ಗಳನ್ನು ನೋಡಿ"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ದಿನ}one{# ದಿನಗಳು}other{# ದಿನಗಳು}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ಗಂಟೆ}one{# ಗಂಟೆಗಳು}other{# ಗಂಟೆಗಳು}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"ಟಿಪ್ಪಣಿಗಳು ಆ್ಯಪ್"</string> <string name="role_notes_description" msgid="8496852798616883551">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಟಿಪ್ಪಣಿಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ಆ್ಯಪ್ಗಳು"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ಟಿಪ್ಪಣಿಗಳು"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ಡೀಫಾಲ್ಟ್ ವಾಲೆಟ್ ಆ್ಯಪ್"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet ಆ್ಯಪ್"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"ವಾಲೆಟ್ ಆ್ಯಪ್ಗಳು ನಿಮ್ಮ ಕ್ರೆಡಿಟ್ ಮತ್ತು ಲಾಯಲ್ಟಿ ಕಾರ್ಡ್ಗಳು, ಕಾರ್ ಕೀಗಳು ಮತ್ತು ವಿವಿಧ ವಹಿವಾಟುಗಳಿಗೆ ಸಹಾಯ ಮಾಡುವ ಇತರ ವಿಷಯಗಳನ್ನು ಸಂಗ್ರಹಿಸಬಹುದು."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್ ಅನ್ನು ನಿಮ್ಮ ಡೀಫಾಲ್ಟ್ ವಾಲೆಟ್ ಆ್ಯಪ್ ಆಗಿ ಸೆಟ್ ಮಾಡಬೇಕೆ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ಯಾವುದೇ ಅನುಮತಿಗಳ ಅಗತ್ಯವಿಲ್ಲ"</string> <string name="request_role_current_default" msgid="738722892438247184">"ಪ್ರಸ್ತುತ ಡೀಫಾಲ್ಟ್"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ಮತ್ತೆ ಕೇಳಬೇಡ"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ಡೀಫಾಲ್ಟ್ ಆಗಿ ಸೆಟ್ ಮಾಡಿ"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ಡೇಟಾ ಹಂಚಿಕೆ ಅಪ್ಡೇಟ್ಗಳು"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"ಕೆಲವು ಆ್ಯಪ್ಗಳು, ನಿಮ್ಮ ಸ್ಥಳ ಡೇಟಾವನ್ನು ಅವು ಹಂಚಿಕೊಳ್ಳಬಹುದಾದ ವಿಧಾನವನ್ನು ಬದಲಾಯಿಸಿವೆ"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> ಸಮಯಕ್ಕೆ ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲಾಗಿದೆ"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"ನಿನ್ನೆ <xliff:g id="TIME_DATE">%1$s</xliff:g> ಸಮಯಕ್ಕೆ ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲಾಗಿದೆ"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g> ಸಮಯಕ್ಕೆ ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲಾಗಿದೆ"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ನಿಮ್ಮ ಒನ್-ಟೈಮ್ ಪಾಸ್ವರ್ಡ್ 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"ನಿರ್ಬಂಧಿಸಲಾದ ಸೆಟ್ಟಿಂಗ್"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಗಾಗಿ, ಈ ಸೆಟ್ಟಿಂಗ್ ಪ್ರಸ್ತುತ ಲಭ್ಯವಿಲ್ಲ."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g> ಅನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಆ್ಯಪ್ಗೆ ನಿರಾಕರಿಸಲಾಗಿದೆ"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಮತ್ತು ಹಣಕಾಸಿನ ಮಾಹಿತಿಯನ್ನು ಅಪಾಯಕ್ಕೆ ಸಿಲುಕಿಸಬಹುದಾದ ಸೂಕ್ಷ್ಮ ಅನುಮತಿಗೆ ಆ್ಯಪ್ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ವಿನಂತಿಸಿದೆ.<xliff:g id="ID_1"><br><br></xliff:g>.ಈ ನಿರ್ಬಂಧಿತ ಅನುಮತಿಯಿಲ್ಲದೆ ಆ್ಯಪ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರುವ ಸಾಧ್ಯತೆಯಿದೆ. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೇಗೆ ಅನುಮತಿಸುವುದು ಎಂಬುದನ್ನು ತಿಳಿಯಿರಿ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ಡೀಫಾಲ್ಟ್ <xliff:g id="ROLE_NAME">%1$s</xliff:g> ಆಗಿರಲು ಆ್ಯಪ್ಗೆ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ನಿರಾಕರಿಸಲಾಗಿದೆ"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಮತ್ತು ಹಣಕಾಸಿನ ಮಾಹಿತಿಯನ್ನು ಅಪಾಯಕ್ಕೆ ಸಿಲುಕಿಸಬಹುದಾದ ಸೂಕ್ಷ್ಮ ಅನುಮತಿಗಳಿಗೆ ಆ್ಯಪ್ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ವಿನಂತಿಸಿದೆ.<xliff:g id="ID_1"><br><br></xliff:g>ಈ ನಿರ್ಬಂಧಿತ ಅನುಮತಿಗಳಿಲ್ಲದೆ ಆ್ಯಪ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರುವ ಸಾಧ್ಯತೆಯಿದೆ. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೇಗೆ ಅನುಮತಿಸುವುದು ಎಂಬುದನ್ನು ತಿಳಿಯಿರಿ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ಆ್ಯಪ್ಗೆ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ನಿರಾಕರಿಸಲಾಗಿದೆ"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ಈ ಅನುಮತಿಗೆ ಆ್ಯಕ್ಸೆಸ್ ನೀಡುವುದರಿಂದ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಮತ್ತು ಹಣಕಾಸು ಮಾಹಿತಿಯು ಅಪಾಯಕ್ಕೆ ಸಿಲುಕಬಹುದು.<xliff:g id="ID_1"><br><br></xliff:g>ಈ ನಿರ್ಬಂಧಿತ ಅನುಮತಿಯಿಲ್ಲದೆ ಆ್ಯಪ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರುವ ಸಾಧ್ಯತೆಯಿದೆ. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೇಗೆ ಅನುಮತಿಸುವುದು ಎಂಬುದನ್ನು ತಿಳಿಯಿರಿ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ಸರಿ"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"ಅನುಮತಿ ವಿನಂತಿಯನ್ನು ನಿಗ್ರಹಿಸಲಾಗಿದೆ"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ಈ ಆ್ಯಪ್ ಹೆಚ್ಚುವರಿ ಅನುಮತಿಗಳನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ, ಆದರೆ ಸ್ಟ್ರೀಮಿಂಗ್ ಸೆಶನ್ನಲ್ಲಿ ಅನುಮತಿಗಳನ್ನು ನೀಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಮೊದಲು ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಅನುಮತಿ ನೀಡಿ."</string> </resources> diff --git a/PermissionController/res/values-ko-v34/strings.xml b/PermissionController/res/values-ko-v34/strings.xml index 7b3091170..6e3b42dbb 100644 --- a/PermissionController/res/values-ko-v34/strings.xml +++ b/PermissionController/res/values-ko-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"건강 데이터에 대한 앱 액세스 제어"</string> <string name="location_settings" msgid="8863940440881290182">"위치 정보 액세스"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"앱 및 서비스에 적용됩니다. 설정이 꺼져 있어도 긴급 전화번호로 전화를 걸 때 마이크 데이터가 계속 공유될 수 있습니다."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"앱 및 서비스에 적용"</string> </resources> diff --git a/PermissionController/res/values-ko-watch/strings.xml b/PermissionController/res/values-ko-watch/strings.xml index fbe07c16c..89299a26f 100644 --- a/PermissionController/res/values-ko-watch/strings.xml +++ b/PermissionController/res/values-ko-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"변경할 수 없음"</string> <string name="generic_yes" msgid="2489207724988649846">"예"</string> <string name="generic_cancel" msgid="2631708607129269698">"취소"</string> + <string name="permission_access_always" msgid="2107115233573823032">"항상"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"앱을 사용 중일 때"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"항상"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"앱을 사용 중일 때"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"항상"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"앱을 사용 중일 때"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"항상"</string> </resources> diff --git a/PermissionController/res/values-ko/strings.xml b/PermissionController/res/values-ko/strings.xml index cc06d56d7..190c0b9ac 100644 --- a/PermissionController/res/values-ko/strings.xml +++ b/PermissionController/res/values-ko/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"모든 권한"</string> <string name="other_permissions" msgid="2901186127193849594">"다른 앱 기능"</string> <string name="permission_request_title" msgid="8790310151025020126">"권한 요청"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear에서는 설치/제거 작업이 지원되지 않습니다"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>에서 액세스하도록 허용할 항목 선택"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) 업데이트되었습니다. 이 앱에서 액세스하도록 허용할 항목을 선택하세요."</string> <string name="review_button_cancel" msgid="2191147944056548886">"취소"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"정확한 위치가 사용 중지된 경우 앱이 대략적인 위치 정보에 액세스할 수 있습니다."</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> 액세스 권한"</string> <string name="app_permission_header" msgid="2951363137032603806">"이 앱의 <xliff:g id="PERM">%1$s</xliff:g> 액세스 권한"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"이 앱의 <xliff:g id="DEVICE_NAME">%2$s</xliff:g> <xliff:g id="PERM">%1$s</xliff:g> 액세스 권한"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g> 권한 모두 보기"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"이 권한이 있는 앱 모두 보기"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"어시스턴트 마이크 사용 표시"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"앱이 사용되지 않는 경우 권한 삭제"</string> <string name="unused_apps_label" msgid="2595428768404901064">"권한을 삭제하고 여유 공간 확보"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"사용하지 않을 때 앱 활동 일시중지"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"사용하지 않는 앱 관리"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"권한 제거, 임시 파일 삭제, 알림 중지"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"권한 제거, 임시 파일 삭제, 알림 중지, 앱 보관처리"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"데이터 보호를 위해 몇 개월 동안 앱을 사용하지 않으면 앱의 권한이 삭제됩니다."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"데이터 보호를 위해 몇 개월 동안 앱을 사용하지 않으면 다음 권한이 삭제됩니다. <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"데이터 보호를 위해 몇 개월 동안 사용하지 않은 앱에서 권한이 삭제되었습니다."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"모든 파일을 관리하도록 허용됨"</string> <string name="ask_header" msgid="2633816846459944376">"항상 확인"</string> <string name="denied_header" msgid="903209608358177654">"허용되지 않음"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>의 <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"모든 파일에 액세스할 수 있는 앱 더보기"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1일}other{#일}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{#시간}other{#시간}}"</string> @@ -351,7 +353,7 @@ <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"이 앱이 내 화면, 작업, 입력 내용을 보고 작업을 실행하며 디스플레이를 제어할 수 있습니다."</string> <string name="role_assistant_label" msgid="4727586018198208128">"기본 디지털 어시스턴트 앱"</string> <string name="role_assistant_short_label" msgid="3369003713187703399">"디지털 어시스턴트 앱"</string> - <string name="role_assistant_description" msgid="6622458130459922952">"지원 앱은 화면에 표시된 정보에 맞게 도움을 줄 수 있습니다. 일부 앱은 통합된 지원을 제공하기 위해 런처와 음성 입력 서비스를 모두 지원합니다."</string> + <string name="role_assistant_description" msgid="6622458130459922952">"지원 앱은 화면에 표시된 정보를 기반으로 도움을 줄 수 있습니다. 일부 앱은 통합된 지원을 제공하기 위해 런처와 음성 입력 서비스를 모두 지원합니다."</string> <string name="role_browser_label" msgid="2877796144554070207">"기본 브라우저 앱"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"브라우저 앱"</string> <string name="role_browser_description" msgid="3465253637499842671">"인터넷에 액세스하고 탭하는 링크를 표시하는 앱"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"메모 앱"</string> <string name="role_notes_description" msgid="8496852798616883551">"이 기기에서 메모할 수 있게 해주는 앱"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"메모"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"기본 월렛 앱"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"월렛 앱"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"다양한 형태의 거래에 사용할 수 있도록 월렛 앱에 신용카드 및 포인트 카드, 자동차 키 등을 저장할 수 있습니다."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 기본 월렛 앱으로 설정하시겠습니까?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"권한 필요 없음"</string> <string name="request_role_current_default" msgid="738722892438247184">"현재 기본 앱"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"다시 묻지 않음"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"기본 앱으로 설정"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"데이터 공유 업데이트"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"일부 앱에서 위치 데이터 공유 방법이 변경되었습니다."</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"설정"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>에 액세스함"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"어제 <xliff:g id="TIME_DATE">%1$s</xliff:g>에 액세스함"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>에 액세스함"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"일회용 비밀번호는 132435입니다"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"제한된 설정"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"보안을 위해 이 설정은 현재 사용할 수 없습니다."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>에 대한 앱의 액세스가 거부됨"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"앱에서 개인 정보 및 금융 정보가 위험에 노출될 수 있는 민감한 권한에 대한 액세스를 요청했습니다.<xliff:g id="ID_1"><br><br></xliff:g>이 제한된 권한 없이는 앱이 제대로 작동하지 않을 수 있습니다. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>액세스 허용 방법 알아보기</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"앱을 기본 <xliff:g id="ROLE_NAME">%1$s</xliff:g>으로 사용하기 위한 앱의 액세스가 거부됨"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"앱에서 개인 정보 및 금융 정보가 위험에 노출될 수 있는 민감한 권한에 대한 액세스를 요청했습니다.<xliff:g id="ID_1"><br><br></xliff:g>이 제한된 권한 없이는 앱이 제대로 작동하지 않을 수 있습니다. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>액세스 허용 방법 알아보기</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"앱의 액세스가 거부됨"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"이 권한에 액세스하면 개인 정보 및 금융 정보가 위험에 노출될 수 있습니다.<xliff:g id="ID_1"><br><br></xliff:g>이 제한된 권한 없이는 앱이 제대로 작동하지 않을 수 있습니다. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>액세스 허용 방법 알아보기</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"자세히 알아보기"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"확인"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"권한 요청 거부됨"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"앱에서 추가 권한을 요청합니다. 그러나 스트리밍 세션에서는 권한을 부여할 수 없습니다. 휴대전화에서 먼저 권한을 부여하세요."</string> </resources> diff --git a/PermissionController/res/values-ky-v34/strings.xml b/PermissionController/res/values-ky-v34/strings.xml index 15fc8424e..0753f01af 100644 --- a/PermissionController/res/values-ky-v34/strings.xml +++ b/PermissionController/res/values-ky-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Колдонмо үчүн ден соолукка байланыштуу нерселердин жеткиликтүүлүгүн тескейсиз"</string> <string name="location_settings" msgid="8863940440881290182">"Жайгашкан жерди көрсөтүү"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Колдонмолор жана кызматтар үчүн. Бул параметр өчүп турса да, кырсыктаганда жардамга келчү кызматтын номерине чалганыңызда микрофондогу нерселер өткөрүлүшү мүмкүн."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Колдонмолор жана кызматтар үчүн"</string> </resources> diff --git a/PermissionController/res/values-ky-watch/strings.xml b/PermissionController/res/values-ky-watch/strings.xml index d6ca47fc1..84b891bee 100644 --- a/PermissionController/res/values-ky-watch/strings.xml +++ b/PermissionController/res/values-ky-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Өзгөртүүгө болбойт"</string> <string name="generic_yes" msgid="2489207724988649846">"Ооба"</string> <string name="generic_cancel" msgid="2631708607129269698">"Жок"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Ар дайым"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Колдонмону пайдаланууда"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Ар дайым"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Колдонмону пайдаланууда"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Ар дайым"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Колдонмону пайдаланууда"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Ар дайым"</string> </resources> diff --git a/PermissionController/res/values-ky/strings.xml b/PermissionController/res/values-ky/strings.xml index 1f1ee13a1..3ee9669a5 100644 --- a/PermissionController/res/values-ky/strings.xml +++ b/PermissionController/res/values-ky/strings.xml @@ -48,7 +48,7 @@ <string name="deny_permission_deny_and_dont_ask_again" msgid="6106035221490102341">"Тыюу салам жана экинчи суралбасын"</string> <string name="permission_revoked_count" msgid="4785082705441547086">"<xliff:g id="COUNT">%1$d</xliff:g> өчүрүлгөн"</string> <string name="permission_revoked_all" msgid="3397649017727222283">"баары өчүрүлгөн"</string> - <string name="permission_revoked_none" msgid="9213345075484381180">"эч бири өчүрүлгөн жок"</string> + <string name="permission_revoked_none" msgid="9213345075484381180">"эч бири өчкөн жок"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"Уруксат берүү"</string> <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Бардык учурда уруксат берилет"</string> <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Колдонмо ачылып турганда"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Бардык уруксаттар"</string> <string name="other_permissions" msgid="2901186127193849594">"Колдонмонун башка мүмкүнчүлүктөрү"</string> <string name="permission_request_title" msgid="8790310151025020126">"Уруксат суроо"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Орнотуу/чыгарып салуу аракеттери Android Wear\'де колдоого алынбайт."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосу үчүн уруксаттарды тандаңыз"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> жаңырды. Ал үчүн уруксаттарды тандаңыз."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Жок"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Жайгашкан жерди тагыраак аныктоо мүмкүнчүлүгү өчүрүлгөн болсо, колдонмолор турган жериңизди болжолдоп аныктай алышат"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> уруксаттары"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: бул колдонмого уруксат берүү"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүндө бул колдонмо үчүн <xliff:g id="PERM">%1$s</xliff:g> уруксаты"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Бардык <xliff:g id="APP">%1$s</xliff:g> уруксаттарын көрүү"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Ушундай уруксат берилген бардык колдонмолорду көрүү"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Кошумча микрофондун иштешин көрсөтүү"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Эгер колдонмо пайдаланылбаса, уруксаттар өчүрүлсүн"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Уруксаттарды өчүрүп, орун бошотуу"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Колдонулбаган колдонмолордун ишин тындыруу"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Колдонмо колдонулбаса, аны тескеңиз"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Уруксаттар өчүрүлүп, убактылуу файлдар тазаланып, билдирмелер келбей калат"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Уруксаттарды алып салып, убактылуу файлдарды жок кылып, билдирмелерди токтотуңуз жана колдонмону архивдеңиз"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Эгер колдонмо бир нече ай пайдаланылбаса, жеке маалыматтарыңызды коргоо үчүн бул колдонмого берилген уруксаттар өчүрүлөт."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Эгер колдонмо бир нече ай пайдаланылбаса, жеке дайын-даректериңизди коргоо максатында төмөнкү уруксаттар өчүрүлөт: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Жеке дайын-даректериңизди коргоо максатында, бир нече айдан бери ачылбаган колдонмолордогу уруксаттар өчүрүлдү."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Бардык файлдарды башкарууга уруксат берилген"</string> <string name="ask_header" msgid="2633816846459944376">"Ар дайым суралсын"</string> <string name="denied_header" msgid="903209608358177654">"Тыюу салынган"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>–<xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Дагы кайсы колдонмолорго бардык файлдар жеткиликтүү?"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 күн}other{# күн}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# саат}other{# саат}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Кыска жазуулар колдонмосу"</string> <string name="role_notes_description" msgid="8496852798616883551">"Түзмөгүңүздө кыска жазууларды терүү мүмкүнчүлүгүн берген колдонмолор"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"кыска жазуулар"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Демейки капчык колдонмосу"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Капчык колдонмосу"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Капчык колдонмосунда насыя жана туруктуу кардардын карталары, унаанын ачкычтары сыяктуу санарип нерселер сакталат. Алардын жардамы менен ар кандай транзакцияларды аткара аласыз."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> демейки капчык колдонмоңуз катары тууралансынбы?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Уруксаттардын кереги жок"</string> <string name="request_role_current_default" msgid="738722892438247184">"Учурдагы демейки колдонмо"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Экинчи суралбасын"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Демейки катары коюу"</string> @@ -610,7 +617,7 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"Микрофонду колдонуу"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Колдонмолор жана кызматтар үчүн"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Кырсыктаганда жардамга келчү кызматка чалганда, микрофондогу нерселер бөлүшүлүшү мүмкүн."</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"Кайда жүргөнүңүздү көрүүгө уруксаты бар колдонмолорду жана кызматтарды көрүү"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"Кайда жүргөнүңүздү көрө алган колдонмолор менен кызматтардын тизмеси"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Алмашуу буферин пайдалануу мүмкүнчүлүгүн көрсөтүү"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Колдонмолор көчүрүлгөн текстти, сүрөттөрдү же башка нерселерди пайдаланганда билдирүүлөр көрүнөт"</string> <string name="show_password_title" msgid="2877269286984684659">"Сырсөз көрүнсүн"</string> @@ -643,9 +650,25 @@ <string name="learn_about_data_sharing" msgid="4200480587079488045">"Маалыматтарды бөлүшүү жөнүндө кеңири маалымат"</string> <string name="shares_location_with_third_parties" msgid="2278051743742057767">"Жүргөн жериңиз тууралуу маалымат үчүнчү тараптар менен бөлүшүлүп жатат"</string> <string name="shares_location_with_third_parties_for_advertising" msgid="1918588064014480513">"Жүргөн жериңизди үчүнчү тараптар жарнамалоо же маркетинг максатында билип турушат"</string> - <string name="updated_in_last_days" msgid="8371811947153042322">"{count,plural, =0{Кечээ жаңыртылды}=1{Кечээ жаңыртылды}other{# күн мурда жаңыртылды}}"</string> + <string name="updated_in_last_days" msgid="8371811947153042322">"{count,plural, =0{Кечээ жаңырды}=1{Кечээ жаңырды}other{# күн мурда жаңырды}}"</string> <string name="no_updates_at_this_time" msgid="9031085635689982935">"Азырынча жаңыртуулар жок"</string> <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Маалыматты бөлүшүү жаңыртуулары"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Айрым колдонмолор турган жериңизди билдирүү ыкмасын өзгөрттү"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Параметрлер"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Cаат <xliff:g id="TIME_DATE">%1$s</xliff:g> колдонулду"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Кечээ саат <xliff:g id="TIME_DATE">%1$s</xliff:g> колдонулду"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> саат <xliff:g id="TIME_DATE_1">%2$s</xliff:g> колдонулду"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Бир жолу гана колдонулуучу кодуңуз: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Чектелген функция"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Коопсуздук максатында бул параметр азырынча иштебейт."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Колдонмого <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> параметрин колдонууга тыюу салынды"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Колдонмо жеке жана каржы маалыматыңыздын коопсуздугуна коркунуч жаратышы мүмкүн болгон купуя маалыматты көрүүгө уруксат сурады.<xliff:g id="ID_1"><br><br></xliff:g>Мындай чектелген уруксат берилбесе, колдонмо ойдогудай иштебеши ыктымал. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Мүмкүнчүлүк берүү жөнүндө кеңири маалымат</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Колдонмого демейки <xliff:g id="ROLE_NAME">%1$s</xliff:g> ролун колдонууга тыюу салынды"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Колдонмо жеке жана каржы маалыматыңыздын коопсуздугуна коркунуч жаратышы мүмкүн болгон купуя маалыматты көрүүгө уруксаттарды сурады.<xliff:g id="ID_1"><br><br></xliff:g>Мындай чектелген уруксаттар берилбесе, колдонмо ойдогудай иштебеши ыктымал. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Мүмкүнчүлүк берүү жөнүндө кеңири маалымат</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Колдонмого мүмкүнчүлүк алууга тыюу салынды"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Бул уруксатты берсеңиз, жеке жана каржы маалыматыңыздын коопсуздугуна коркунуч жаралышы мүмкүн.<xliff:g id="ID_1"><br><br></xliff:g>Мындай чектелген уруксат берилбесе, колдонмо ойдогудай иштебеши ыктымал. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Мүмкүнчүлүк берүү жөнүндө кеңири маалымат</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Кеңири маалымат"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Жарайт"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Уруксат берүү сурамы четке кагылды"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Бул колдонмо кошумча уруксаттарды берүүнү суранып жатат, бирок алып ойнотуу сеансында уруксаттарды берүүгө болбойт. Адегенде телефондо уруксат бериңиз."</string> </resources> diff --git a/PermissionController/res/values-lo-v34/strings.xml b/PermissionController/res/values-lo-v34/strings.xml index 431b80ec1..07e965359 100644 --- a/PermissionController/res/values-lo-v34/strings.xml +++ b/PermissionController/res/values-lo-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ຈັດການສິດເຂົ້າເຖິງຂອງແອັບຫາຂໍ້ມູນສຸຂະພາບ"</string> <string name="location_settings" msgid="8863940440881290182">"ສິດເຂົ້າເຖິງສະຖານທີ່"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ສຳລັບແອັບ ແລະ ບໍລິການຕ່າງໆ. ຫາກປິດການຕັ້ງຄ່ານີ້ໄວ້, ຂໍ້ມູນໄມໂຄຣໂຟນອາດຍັງຖືກແບ່ງປັນເມື່ອທ່ານໂທຫາເບີໂທສຸກເສີນ"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ສຳລັບແອັບ ແລະ ບໍລິການຕ່າງໆ"</string> </resources> diff --git a/PermissionController/res/values-lo-watch/strings.xml b/PermissionController/res/values-lo-watch/strings.xml index f0c39134f..bc1fbad9f 100644 --- a/PermissionController/res/values-lo-watch/strings.xml +++ b/PermissionController/res/values-lo-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ບໍ່ສາມາດປ່ຽນແປງໄດ້"</string> <string name="generic_yes" msgid="2489207724988649846">"ໄປ"</string> <string name="generic_cancel" msgid="2631708607129269698">"ຍົກເລີກ"</string> + <string name="permission_access_always" msgid="2107115233573823032">"ຕະຫຼອດເວລາ"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ໃນເວລາໃຊ້ແອັບ"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"ຕະຫຼອດເວລາ"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ໃນເວລາໃຊ້ແອັບ"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"ຕະຫຼອດເວລາ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ໃນເວລາໃຊ້ແອັບ"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"ຕະຫຼອດເວລາ"</string> </resources> diff --git a/PermissionController/res/values-lo/strings.xml b/PermissionController/res/values-lo/strings.xml index b78db29c8..c8e9c44c7 100644 --- a/PermissionController/res/values-lo/strings.xml +++ b/PermissionController/res/values-lo/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ທຸກການອະນຸຍາດ"</string> <string name="other_permissions" msgid="2901186127193849594">"ຄວາມສາມາດອື່ນຂອງແອັບ"</string> <string name="permission_request_title" msgid="8790310151025020126">"ການຮ້ອງຂໍການອະນຸຍາດ"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"ຕິດຕັ້ງ/ຖອນການຕິດຕັ້ງ ຄຳສັ່ງທີ່ບໍ່ຮອງຮັບຢູ່ Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"ເລືອກວ່າຈະອະນຸຍາດໃຫ້ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ເຂົ້າເຖິງຫຍັງໄດ້ແດ່"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"ອັບເດດ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ແລ້ວ. ກະລຸນາເລືອກວ່າຈະໃຫ້ແອັບນີ້ເຂົ້າເຖິງຫຍັງໄດ້ແດ່."</string> <string name="review_button_cancel" msgid="2191147944056548886">"ຍົກເລີກ"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"ເມື່ອປິດສະຖານທີ່ແບບລະອຽດໄວ້ແລ້ວ, ແອັບຕ່າງໆຈະສາມາດເຂົ້າເຖິງສະຖານທີ່ໂດຍປະມານຂອງທ່ານໄດ້"</string> <string name="app_permission_title" msgid="2090897901051370711">"ສິດອະນຸຍາດ <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"ສິດເຂົ້າເຖິງ <xliff:g id="PERM">%1$s</xliff:g> ສຳລັບແອັບນີ້"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> ເຂົ້າເຖິງແອັບນີ້ຢູ່ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"ເບິ່ງສິດອະນຸຍາດ <xliff:g id="APP">%1$s</xliff:g> ທັງໝົດ"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ເບິ່ງແອັບທັງໝົດທີ່ມີສິດອະນຸຍາດນີ້"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"ສະແດງການໃຊ້ໄມໂຄຣໂຟນຂອງຜູ້ຊ່ວຍ"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ລຶບສິດອະນຸຍາດຫາກບໍ່ໄດ້ໃຊ້ແອັບ"</string> <string name="unused_apps_label" msgid="2595428768404901064">"ລຶບການອະນຸຍາດອອກ ແລະ ສ້າງພື້ນທີ່ຫວ່າງ"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"ຢຸດການເຄື່ອນໄຫວແອັບຊົ່ວຄາວຫາກບໍ່ໄດ້ໃຊ້"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ຈັດການແອັບຫາກບໍ່ໄດ້ໃຊ້"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ລຶບການອະນຸຍາດອອກ, ລຶບໄຟລ໌ຊົ່ວຄາວ ແລະ ຢຸດການແຈ້ງເຕືອນ"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ລຶບການອະນຸຍາດອອກ, ລຶບໄຟລ໌ຊົ່ວຄາວ, ຢຸດການແຈ້ງເຕືອນ ແລະ ເກັບແອັບໄວ້ໃນແຟ້ມ"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"ເພື່ອປົກປ້ອງຂໍ້ມູນຂອງທ່ານ, ສິດອະນຸຍາດສຳລັບແອັບນີ້ຈະຖືກລຶບອອກຫາກບໍ່ໄດ້ໃຊ້ແອັບສອງສາມເດືອນ."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"ເພື່ອປົກປ້ອງຂໍ້ມູນຂອງທ່ານ, ຫາກບໍ່ໄດ້ໃຊ້ແອັບສອງສາມເດືອນ, ສິດອະນຸຍາດຕໍ່ໄປນີ້ຈະຖືກລຶບອອກ: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"ເພື່ອປົກປ້ອງຂໍ້ມູນຂອງທ່ານ, ລະບົບໄດ້ລຶບສິດອະນຸຍາດອອກຈາກແອັບຕ່າງໆທີ່ທ່ານບໍ່ໄດ້ໃຊ້ສອງສາມເດືອນແລ້ວ."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ອະນຸຍາດໃຫ້ຈັດການໄຟລ໌ທັງໝົດແລ້ວ"</string> <string name="ask_header" msgid="2633816846459944376">"ຖາມທຸກເທື່ອ"</string> <string name="denied_header" msgid="903209608358177654">"ບໍ່ອະນຸຍາດ"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> ໃນ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ເບິ່ງແອັບເພີ່ມເຕີມທີ່ສາມາດເຂົ້າເຖິງໄຟລ໌ທັງໝົດໄດ້"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ມື້}other{# ມື້}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ຊົ່ວໂມງ}other{# ຊົ່ວໂມງ}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"ແອັບຂຽນບັນທຶກ"</string> <string name="role_notes_description" msgid="8496852798616883551">"ແອັບທີ່ອະນຸຍາດໃຫ້ທ່ານຈົດບັນທຶກຢູ່ອຸປະກອນຂອງທ່ານ"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ບັນທຶກ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ແອັບ Wallet ເລີ່ມຕົ້ນ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"ແອັບ Wallet"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"ແອັບ Wallet ສາມາດຈັດເກັບບັດເຄຣດິດ ແລະ ບັດສະມາຊິກ, ກະແຈລົດ ແລະ ສິ່ງອື່ນໆຂອງທ່ານເພື່ອຊ່ວຍໃນການເຮັດທຸລະກຳຮູບແບບຕ່າງໆ."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"ຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ເປັນແອັບ Wallet ເລີ່ມຕົ້ນຂອງທ່ານບໍ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ບໍ່ຈຳເປັນຕ້ອງມີການອະນຸຍາດ"</string> <string name="request_role_current_default" msgid="738722892438247184">"ຄ່າເລີ່ມຕົ້ນປັດຈຸບັນ"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ບໍ່ຕ້ອງຖາມອີກ"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ຕັ້ງເປັນຄ່າເລີ່ມຕົ້ນ"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ການອັບເດດການແບ່ງປັນຂໍ້ມູນ"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"ບາງແອັບໄດ້ປ່ຽນແປງວິທີທີ່ແອັບອາດແບ່ງປັນຂໍ້ມູນສະຖານທີ່ຂອງທ່ານແລ້ວ"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ການຕັ້ງຄ່າ"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"ເຂົ້າເຖິງເມື່ອ <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"ເຂົ້າເຖິງມື້ວານນີ້ເມື່ອ <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"ເຂົ້າເຖິງເມື່ອ <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ລະຫັດຜ່ານແບບໃຊ້ໄດ້ເທື່ອດຽວຂອງທ່ານແມ່ນ 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"ການຕັ້ງຄ່າທີ່ຈຳກັດ"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ຕອນນີ້ຈຶ່ງບໍ່ສາມາດໃຊ້ການຕັ້ງຄ່ານີ້ໄດ້."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"ແອັບຖືກປະຕິເສດສິດເຂົ້າເຖິງຫາ <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"ແອັບໄດ້ຮ້ອງຂໍການສິດເຖິງການອະນຸຍາດທີ່ລະອຽດອ່ອນ ເຊິ່ງສາມາດເຮັດໃຫ້ຂໍ້ມູນສ່ວນຕົວ ແລະ ຂໍ້ມູນການເງິນຂອງທ່ານມີຄວາມສ່ຽງ.<xliff:g id="ID_1"><br><br></xliff:g>ມັນເປັນໄປໄດ້ວ່າແອັບດັ່ງກ່າວຈະບໍ່ເຮັດວຽກຢ່າງຖືກຕ້ອງໂດຍບໍ່ມີການອະນຸຍາດທີ່ຖືກຈຳກັດໄວ້ນີ້. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ສຶກສາວິທີອະນຸຍາດສິດເຂົ້າເຖິງ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ແອັບຖືກປະຕິເສດສິດເຂົ້າເຖິງໃຫ້ເປັນ <xliff:g id="ROLE_NAME">%1$s</xliff:g> ຄ່າເລີ່ມຕົ້ນ"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"ແອັບໄດ້ຮ້ອງຂໍການສິດເຖິງການອະນຸຍາດທີ່ລະອຽດອ່ອນ ເຊິ່ງສາມາດເຮັດໃຫ້ຂໍ້ມູນສ່ວນຕົວ ແລະ ຂໍ້ມູນການເງິນຂອງທ່ານມີຄວາມສ່ຽງ.<xliff:g id="ID_1"><br><br></xliff:g>ມັນເປັນໄປໄດ້ວ່າແອັບດັ່ງກ່າວຈະບໍ່ເຮັດວຽກຢ່າງຖືກຕ້ອງໂດຍບໍ່ມີການອະນຸຍາດທີ່ຖືກຈຳກັດໄວ້ເຫຼົ່ານີ້. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ສຶກສາວິທີອະນຸຍາດສິດເຂົ້າເຖິງ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ແອັບຖືກປະຕິເສດສິດເຂົ້າເຖິງ"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ເຂົ້າເຖິງການອະນຸຍາດນີ້ສາມາດເຮັດໃຫ້ຂໍ້ມູນສ່ວນຕົວ ແລະ ຂໍ້ມູນການເງິນຂອງທ່ານມີຄວາມສ່ຽງ.<xliff:g id="ID_1"><br><br></xliff:g>ມັນເປັນໄປໄດ້ວ່າແອັບດັ່ງກ່າວຈະບໍ່ເຮັດວຽກຢ່າງຖືກຕ້ອງໂດຍບໍ່ມີການອະນຸຍາດທີ່ຖືກຈຳກັດໄວ້ນີ້. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ສຶກສາວິທີອະນຸຍາດສິດເຂົ້າເຖິງ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ສຶກສາເພີ່ມເຕີມ"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ຕົກລົງ"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"ຄຳຮ້ອງຂໍການອະນຸຍາດຖືກລະງັບ"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ແອັບນີ້ກຳລັງຮ້ອງຂໍການອະນຸຍາດເພີ່ມເຕີມ, ແຕ່ບໍ່ສາມາດໃຫ້ການອະນຸຍາດໃນເຊດຊັນການສະຕຣີມໄດ້. ກະລຸນາໃຫ້ການອະນຸຍາດໃນໂທລະສັບຂອງທ່ານກ່ອນ."</string> </resources> diff --git a/PermissionController/res/values-lt-v34/strings.xml b/PermissionController/res/values-lt-v34/strings.xml index f7a60d198..2546f96e5 100644 --- a/PermissionController/res/values-lt-v34/strings.xml +++ b/PermissionController/res/values-lt-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Programos prieigos prie sveikatos duomenų tvarkymas"</string> <string name="location_settings" msgid="8863940440881290182">"Prieiga prie vietovės"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Programos ir paslaugos. Jei šis nustatymas išjungtas, mikrofono duomenys vis tiek gali būti bendrinami, skambinant pagalbos numeriu"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Programos ir paslaugos"</string> </resources> diff --git a/PermissionController/res/values-lt-watch/strings.xml b/PermissionController/res/values-lt-watch/strings.xml index c852a6508..b875ee94e 100644 --- a/PermissionController/res/values-lt-watch/strings.xml +++ b/PermissionController/res/values-lt-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Negalima pakeisti"</string> <string name="generic_yes" msgid="2489207724988649846">"Taip"</string> <string name="generic_cancel" msgid="2631708607129269698">"Atšaukti"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Visą laiką"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Kai programa naudojama"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Visą laiką"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Kai programa naudojama"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Visą laiką"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Kai programa naudojama"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Visą laiką"</string> </resources> diff --git a/PermissionController/res/values-lt/strings.xml b/PermissionController/res/values-lt/strings.xml index d7fbc6af8..3e87d9cd1 100644 --- a/PermissionController/res/values-lt/strings.xml +++ b/PermissionController/res/values-lt/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Visi leidimai"</string> <string name="other_permissions" msgid="2901186127193849594">"Kitos programos galimybės"</string> <string name="permission_request_title" msgid="8790310151025020126">"Leidimo užklausa"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Diegimo / pašalinimo veiksmai nepalaikomi sistemoje „Wear“."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Pasirinkite, ką norite leisti programai <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pasiekti"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Programa <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> buvo atnaujinta. Pasirinkite, ką norite leisti šiai programai pasiekti."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Atšaukti"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kai tikslios vietovės nustatymo parinktis išjungta, programos gali pasiekti apytikslės vietovės duomenis"</string> <string name="app_permission_title" msgid="2090897901051370711">"Leidimas: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: šios programos prieiga"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g> prieiga šiai programai „<xliff:g id="DEVICE_NAME">%2$s</xliff:g>“"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Žr. visus „<xliff:g id="APP">%1$s</xliff:g>“ leidimus"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Žr. visas programas, kurioms suteiktas šis leidimas"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Rodyti Padėjėjo mikrofono naudojimą"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Pašalinti leidimus, jei programa nenaudojama"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Pašalinti leidimus ir atlaisvinti vietos"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pristabdyti nenaudojamų programų veiklą"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Tvarkyti programą, jei nenaudojama"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Pašalinkite leidimus, ištrinkite laikinus failus ir sustabdykite pranešimus"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Pašalinti leidimus, ištrinti laikinus failus, sustabdyti pranešimus ir archyvuoti programą"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Siekiant apsaugoti duomenis, šios programos leidimai bus pašalinti, jei programos nenaudosite kelis mėnesius."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Siekiant apsaugoti duomenis, jei programos nenaudosite kelis mėnesius, bus pašalinti nurodyti leidimai: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Siekiant apsaugoti duomenis, leidimai buvo pašalinti iš programų, kurių nenaudojote kelis mėnesius"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Leidžiama valdyti visus failus"</string> <string name="ask_header" msgid="2633816846459944376">"Klausti kaskart"</string> <string name="denied_header" msgid="903209608358177654">"Neleidžiama"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> „<xliff:g id="DEVICE_NAME">%2$s</xliff:g>“"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Peržiūrėti daugiau programų, galinčių pasiekti visus failus"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 diena}one{# diena}few{# dienos}many{# dienos}other{# dienų}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# valanda}one{# valanda}few{# valandos}many{# valandos}other{# valandų}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Užrašų programa"</string> <string name="role_notes_description" msgid="8496852798616883551">"Programos, leidžiančios rašyti užrašus jūsų įrenginyje"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"užrašai"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Numatytoji piniginės programa"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Piniginės programa"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Piniginės programos gali saugoti jūsų kredito ir lojalumo kortelių, automobilių raktų ir kitus duomenis, kad lengviau atliktumėte įvairias operacijas."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Nustatyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ kaip numatytąją piniginės programą?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nereikia jokių leidimų"</string> <string name="request_role_current_default" msgid="738722892438247184">"Dabartinė numatytoji"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Daugiau neklausti"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Nustatyti numatytąja"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Duomenų bendrinimo naujiniai"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Kai kuriose programose pakeisti vietovės duomenų bendrinimo metodai"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Nustatymai"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Pasiekta <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Pasiekta vakar <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Pasiekta <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Jūsų vienkartinis slaptažodis yra 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Apribotas nustatymas"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Šis nustatymas šiuo metu nepasiekiamas dėl jūsų saugumo."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Programai prieiga nesuteikta:<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Programa pateikė leidimo pasiekti neskelbtiną informaciją, dėl kurio gali kilti pavojus jūsų asmens ir finansinei informacijai, užklausą.<xliff:g id="ID_1"><br><br></xliff:g>Gali būti, kad be šio apriboto leidimo programa neveiks tinkamai. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Sužinokite, kaip suteikti prieigą</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Programai nesuteikta prieiga kaip numatytojo šio vaidmens: <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Programa pateikė leidimo pasiekti neskelbtiną informaciją, dėl kurio gali kilti pavojus jūsų asmens ir finansinei informacijai, užklausą.<xliff:g id="ID_1"><br><br></xliff:g>Gali būti, kad be šių apribotų leidimų programa neveiks tinkamai. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Sužinokite, kaip suteikti prieigą</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Programai prieiga nesuteikta"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Prieiga prie šio leidimo gali kelti pavojų jūsų asmens ir finansinei informacijai.<xliff:g id="ID_1"><br><br></xliff:g>Gali būti, kad be šio apriboto leidimo programa neveiks tinkamai. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Sužinokite, kaip suteikti prieigą</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Sužinokite daugiau"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Gerai"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Leidimo užklausa atmesta"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ši programa prašo papildomų leidimų, bet jų negalima suteikti per srautinio perdavimo seansą. Leidimą pirmiausia suteikite telefone."</string> </resources> diff --git a/PermissionController/res/values-lv-v34/strings.xml b/PermissionController/res/values-lv-v34/strings.xml index 3c99e3275..649416a32 100644 --- a/PermissionController/res/values-lv-v34/strings.xml +++ b/PermissionController/res/values-lv-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Pārvaldiet lietotņu piekļuvi veselības datiem."</string> <string name="location_settings" msgid="8863940440881290182">"Piekļuve atrašanās vietai"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Lietotnēm un pakalpojumiem. Ja šis iestatījums ir izslēgts, mikrofona dati joprojām var tikt kopīgoti, kad zvanīsiet uz ārkārtas numuru."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Lietotnēm un pakalpojumiem"</string> </resources> diff --git a/PermissionController/res/values-lv-watch/strings.xml b/PermissionController/res/values-lv-watch/strings.xml index 7ee4ab980..b3ca497f6 100644 --- a/PermissionController/res/values-lv-watch/strings.xml +++ b/PermissionController/res/values-lv-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Nevar mainīt"</string> <string name="generic_yes" msgid="2489207724988649846">"Jā"</string> <string name="generic_cancel" msgid="2631708607129269698">"Atcelt"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Vienmēr"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Izmantojot lietotni"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Vienmēr"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Izmantojot lietotni"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Vienmēr"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Izmantojot lietotni"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Vienmēr"</string> </resources> diff --git a/PermissionController/res/values-lv/strings.xml b/PermissionController/res/values-lv/strings.xml index 10b79f45d..4ebc0becd 100644 --- a/PermissionController/res/values-lv/strings.xml +++ b/PermissionController/res/values-lv/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Visas atļaujas"</string> <string name="other_permissions" msgid="2901186127193849594">"Citas lietotnes atļaujas"</string> <string name="permission_request_title" msgid="8790310151025020126">"Atļaujas pieprasījums"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear ierīcē netiek atbalstīta instalēšana/atinstalēšana"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Izvēlieties, kādas piekļuves atļaujas piešķirt lietotnei <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ir atjaunināta. Izvēlieties, kādas piekļuves atļaujas tai piešķirt."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Atcelt"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Ja precīzās atrašanās vietas noteikšana ir izslēgta, lietotnes var piekļūt jūsu aptuvenajai atrašanās vietai."</string> <string name="app_permission_title" msgid="2090897901051370711">"Atļauja: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: šīs lietotnes piekļuve"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Šai lietotnei ir piešķirta piekļuves atļauja “<xliff:g id="PERM">%1$s</xliff:g>” šajā ierīcē: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Skatīt visas lietotnei <xliff:g id="APP">%1$s</xliff:g> piešķirtās atļaujas"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Skatīt visas lietotnes, kam ir šī atļauja"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Rādīt Asistenta mikrofona lietojumu"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Noņemt atļaujas, ja lietotne netiek izmantota"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Noņemt atļaujas un atbrīvot vietu"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Apturēt lietotni, ja tā netiek izmantota"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Pārvaldīt lietotni, ja tā netiek lietota"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Atsaukt atļaujas, dzēst pagaidu failus un izslēgt paziņojumus"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Noņemt atļaujas, dzēst pagaidu failus, apturēt paziņojumus un arhivēt lietotni"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Ja lietotni dažus mēnešus neizmantosiet, tai tiks noņemtas tālāk norādītās atļaujas, lai aizsargātu jūsu datus."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Ja lietotni dažus mēnešus neizmantosiet, tai tiks noņemtas tālāk norādītās atļaujas, lai aizsargātu jūsu datus: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Lai aizsargātu jūsu datus, tika atsauktas atļaujas tām lietotnēm, kas nav izmantotas vairākus mēnešus."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Atļauts pārvaldīt visus failus"</string> <string name="ask_header" msgid="2633816846459944376">"Vaicāt katru reizi"</string> <string name="denied_header" msgid="903209608358177654">"Nav atļauts"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"Atļauja <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> šajā ierīcē: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Skatīt citas lietotnes, kas drīkst piekļūt visiem failiem"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 diena}zero{# dienu}one{# diena}other{# dienas}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# stunda}zero{# stundu}one{# stunda}other{# stundas}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Piezīmju lietotne"</string> <string name="role_notes_description" msgid="8496852798616883551">"Lietotnes, kas ļauj ierīcē veikt piezīmes"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"piezīmes"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Noklusējuma maka lietotne"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Maka lietotne"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Maka lietotnēs var glabāt informāciju par kredītkartēm un lojalitātes kartēm, automašīnas šifratslēgas un citu informāciju, kas palīdz veikt dažādu veidu darījumus."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Vai iestatīt lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> kā noklusējuma maka lietotni?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nav nepieciešamas nekādas atļaujas."</string> <string name="request_role_current_default" msgid="738722892438247184">"Pašreizējais noklusējums"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Nejautāt atkārtoti"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Iest. kā noklusējumu"</string> @@ -614,7 +621,7 @@ <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Rādīt paziņojumus par piekļuvi starpliktuvei"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Rādīt ziņojumu, kad lietotnes piekļūst jūsu nokopētajam tekstam, attēliem vai citam saturam"</string> <string name="show_password_title" msgid="2877269286984684659">"Rādīt paroles"</string> - <string name="show_password_summary" msgid="1110166488865981610">"Rakstot tiek īslaicīgi rādītas rakstzīmes"</string> + <string name="show_password_summary" msgid="1110166488865981610">"Rakstot īslaicīgi rādīt rakstzīmes"</string> <string name="permission_rationale_message_location" msgid="2153841534298068414">"Lietotne norādīja, ka tā var kopīgot atrašanās vietas datus ar trešajām pusēm."</string> <string name="permission_rationale_location_title" msgid="2404797182678793506">"Datu kopīgošana un atrašanās vieta"</string> <string name="permission_rationale_data_sharing_source_title" msgid="6874604543125814316">"Datu kopīgošanas informācijas avots"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Datu kopīgošanas atjauninājumi"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Dažās lietotnēs tika mainīti atrašanās vietas datu kopīgošanas veidi."</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Iestatījumi"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Pēdējā piekļuves reize: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Pēdējā piekļuves reize vakar: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Pēdējā piekļuves reize: <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Jūsu vienreizējā parole ir 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ierobežots iestatījums"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Drošības apsvērumu dēļ šis iestatījums pašlaik nav pieejams."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Lietotnes piekļuve atļaujai “<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>” tika liegta"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Lietotne ir pieprasījusi piekļuvi sensitīvai atļaujai, kas var apdraudēt jūsu personas un finanšu informāciju.<xliff:g id="ID_1"><br><br></xliff:g>Iespējams, lietotne nedarbosies pareizi bez šīs ierobežotās atļaujas. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Uzziniet, kā piešķirt piekļuvi.</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Lietotnes piekļuve noklusējuma lomai “<xliff:g id="ROLE_NAME">%1$s</xliff:g>” tika liegta"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Lietotne ir pieprasījusi piekļuvi sensitīvai atļaujai, kas var apdraudēt jūsu personas un finanšu informāciju.<xliff:g id="ID_1"><br><br></xliff:g>Iespējams, lietotne nedarbosies pareizi bez šīm ierobežotajām atļaujām. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Uzziniet, kā piešķirt piekļuvi.</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Lietotnei tika liegta piekļuve"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Piekļuve šai atļaujai var apdraudēt jūsu personas un finanšu informāciju.<xliff:g id="ID_1"><br><br></xliff:g>Iespējams, lietotne nedarbosies pareizi bez šīs ierobežotās atļaujas. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Uzziniet, kā piešķirt piekļuvi.</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Uzzināt vairāk"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Labi"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Atļaujas pieprasījums bloķēts"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Šī lietotne pieprasa papildu atļaujas, taču atļaujas nevar piešķirt straumēšanas sesijā. Vispirms piešķiriet attiecīgo atļauju savā tālrunī."</string> </resources> diff --git a/PermissionController/res/values-mk-v34/strings.xml b/PermissionController/res/values-mk-v34/strings.xml index e8f9afc25..d2a9cc0de 100644 --- a/PermissionController/res/values-mk-v34/strings.xml +++ b/PermissionController/res/values-mk-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Управувајте со пристапот на апликациите до здравствените податоци"</string> <string name="location_settings" msgid="8863940440881290182">"Пристап до локацијата"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"За апликации и услуги. Ако поставкава е исклучена, податоците од микрофонот може сепак да се споделат кога ќе се јавите на број за итни случаи"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"За апликации и услуги"</string> </resources> diff --git a/PermissionController/res/values-mk-watch/strings.xml b/PermissionController/res/values-mk-watch/strings.xml index 5d37a6175..9b39c1ce1 100644 --- a/PermissionController/res/values-mk-watch/strings.xml +++ b/PermissionController/res/values-mk-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Не може да се смени"</string> <string name="generic_yes" msgid="2489207724988649846">"Да"</string> <string name="generic_cancel" msgid="2631708607129269698">"Откажи"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Цело време"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"При користење на аплик."</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Цело време"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"При користење на аплик."</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Цело време"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"При користење на аплик."</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Цело време"</string> </resources> diff --git a/PermissionController/res/values-mk/strings.xml b/PermissionController/res/values-mk/strings.xml index 3270a4ea6..321ccc57d 100644 --- a/PermissionController/res/values-mk/strings.xml +++ b/PermissionController/res/values-mk/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Сите дозволи"</string> <string name="other_permissions" msgid="2901186127193849594">"Други можности на апликацијата"</string> <string name="permission_request_title" msgid="8790310151025020126">"Барање за дозвола"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Дејствата „Инсталирај/деинсталирај“ не се поддржани на Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Изберете до што може да пристапува <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> е ажурирана. Изберете до што може да пристапува апликацијава."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Откажи"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Кога прецизната локација е исклучена, апликациите може да пристапуваат до приближната локација"</string> <string name="app_permission_title" msgid="2090897901051370711">"Дозвола за <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Пристап до <xliff:g id="PERM">%1$s</xliff:g> за апликацијава"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Пристап до <xliff:g id="PERM">%1$s</xliff:g> за апликацијава на <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Прикажи ги сите дозволи за <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Прикажи ги сите апликации со оваа дозвола"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Прикажи го користењето на микрофонот на „Помошникот“"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Отстрани ги дозволите ако апликацијата не се користи"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Отстранувај дозволи и ослободувај простор"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Паузирај некористени апликации"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Управување со апликацијата при некористење"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Отстранува дозволи, брише привремени датотеки и запира известувања"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Отстранува дозволи, брише привремени датотеки, сопира известувања и ја архивира апликацијата"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"За да се заштитат вашите податоци, дозволите за апликацијава ќе се отстранат ако апликацијата не се користи неколку месеци."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Ако апликацијата не се користи неколку месеци, заради заштита на податоците, ќе се отстранат следниве дозволи: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"За заштита на податоците, отстранети се дозволите од апликациите што не сте ги користеле неколку месеци."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Со дозвола за управување со сите датотеки"</string> <string name="ask_header" msgid="2633816846459944376">"Прашувај секогаш"</string> <string name="denied_header" msgid="903209608358177654">"Без дозвола"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> на <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Прикажи уште апликации што имаат пристап до сите датотеки"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ден}one{# ден}other{# дена}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# час}one{# час}other{# часа}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Апликација за белешки"</string> <string name="role_notes_description" msgid="8496852798616883551">"Апликации што ви овозможуваат да запишувате белешки на вашиот уред"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"белешки"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Стандардна аплик. за паричник"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Апликација за Wallet"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Апликациите за паричник може да ги складираат кредитните и картичките за лојалност, клучевите за автомобилот, како и други работи за олеснување на различните форми на трансакции."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Да се постави <xliff:g id="APP_NAME">%1$s</xliff:g> како стандардна апликација за Wallet?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Не се потребни дозволи"</string> <string name="request_role_current_default" msgid="738722892438247184">"Стандардна апликација сега"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Не прашувај повторно"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Нека биде стандардна"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Промени во споделувањето податоци"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Некои апликации го сменија начинот на кој ја споделуваат вашата локација"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Поставки"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Пристапено: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Пристапено вчера: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Пристапено: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Вашата еднократна лозинка е 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ограничена поставка"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"За ваша безбедност, поставкава е недостапна во моментов."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Барањето за пристап на апликацијата до <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> е одбиено"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Апликацијата побара пристап до дозвола за чувствителни податоци што може да ја загрози безбедноста на вашите лични и финансиски податоци.<xliff:g id="ID_1"><br><br></xliff:g>Можно е апликацијата да не функционира правилно без ограниченава дозвола. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Дознајте повеќе како да дозволите пристап</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Барањето на апликацијата да биде стандарднa <xliff:g id="ROLE_NAME">%1$s</xliff:g> е одбиено"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Апликацијата побара пристап до дозволи за чувствителни податоци што може да ја загрози безбедноста на вашите лични и финансиски податоци.<xliff:g id="ID_1"><br><br></xliff:g>Можно е апликацијата да не функционира правилно без ограничениве дозволи. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Дознајте повеќе како да дозволите пристап</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Барањето за пристап на апликацијата е одбиено"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Пристапот до дозволава може да ја загрози безбедноста на вашите лични и финансиски податоци.<xliff:g id="ID_1"><br><br></xliff:g>Можно е апликацијата да не функционира правилно без ограниченава дозвола. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Дознајте повеќе како да дозволите пристап</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Дознајте повеќе"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Во ред"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Барањето за дозвола е потиснато"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Апликацијава бара дополнителни дозволи, но нив не може да ги доделите во сесија за стриминг. Прво доделете ја дозволата на вашиот телефон."</string> </resources> diff --git a/PermissionController/res/values-ml-v34/strings.xml b/PermissionController/res/values-ml-v34/strings.xml index 7f22bbf9c..74e8015ac 100644 --- a/PermissionController/res/values-ml-v34/strings.xml +++ b/PermissionController/res/values-ml-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"നിങ്ങളുടെ ആരോഗ്യം സംബന്ധിച്ച ഡാറ്റയിലേക്കുള്ള ആപ്പ് ആക്സസ് നിയന്ത്രിക്കുക"</string> <string name="location_settings" msgid="8863940440881290182">"ലൊക്കേഷൻ ആക്സസ്"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ആപ്പുകൾക്കും സേവനങ്ങൾക്കും. ഈ ക്രമീകരണം ഓഫാണെങ്കിൽ, നിങ്ങൾ അടിയന്തര നമ്പറിൽ വിളിക്കുമ്പോഴും മൈക്രോഫോൺ ഡാറ്റ തുടർന്നും പങ്കിട്ടേക്കാം"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ആപ്പുകൾക്കും സേവനങ്ങൾക്കും"</string> </resources> diff --git a/PermissionController/res/values-ml-watch/strings.xml b/PermissionController/res/values-ml-watch/strings.xml index 37ef4e919..2851731c9 100644 --- a/PermissionController/res/values-ml-watch/strings.xml +++ b/PermissionController/res/values-ml-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"മാറ്റാനാവില്ല"</string> <string name="generic_yes" msgid="2489207724988649846">"അതെ"</string> <string name="generic_cancel" msgid="2631708607129269698">"റദ്ദാക്കുക"</string> + <string name="permission_access_always" msgid="2107115233573823032">"എപ്പോഴും"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ആപ്പ് ഉപയോഗിക്കുമ്പോൾ"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"എപ്പോഴും"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ആപ്പ് ഉപയോഗിക്കുമ്പോൾ"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"എപ്പോഴും"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ആപ്പ് ഉപയോഗിക്കുമ്പോൾ"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"എപ്പോഴും"</string> </resources> diff --git a/PermissionController/res/values-ml/strings.xml b/PermissionController/res/values-ml/strings.xml index 2403dc6d3..8cf164419 100644 --- a/PermissionController/res/values-ml/strings.xml +++ b/PermissionController/res/values-ml/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"എല്ലാ അനുമതികളും"</string> <string name="other_permissions" msgid="2901186127193849594">"മറ്റ് ആപ്പ് ശേഷികൾ"</string> <string name="permission_request_title" msgid="8790310151025020126">"അനുമതി അഭ്യർത്ഥന"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"ഇൻസ്റ്റാൾ/അൺഇൻസ്റ്റാൾ ചെയ്യുന്നതിന് Wear-ൽ പിന്തുണയില്ല."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"എന്തൊക്കെ ആക്സസ് ചെയ്യാനാണ് <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ആപ്പിനെ അനുവദിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> അപ്ഡേറ്റ് ചെയ്തിരിക്കുന്നു. എന്തൊക്കെ ആക്സസ് ചെയ്യാൻ ഈ ആപ്പിനെ അനുവദിക്കണമെന്ന് തിരഞ്ഞെടുക്കുക."</string> <string name="review_button_cancel" msgid="2191147944056548886">"റദ്ദാക്കുക"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"കൃത്യമായ ലൊക്കേഷൻ ഓഫാകുമ്പോൾ, ആപ്പുകൾക്ക് നിങ്ങളുടെ ഏകദേശ ലൊക്കേഷൻ ആക്സസ് ചെയ്യാനാകും"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> അനുമതി"</string> <string name="app_permission_header" msgid="2951363137032603806">"ഈ ആപ്പിനുള്ള <xliff:g id="PERM">%1$s</xliff:g> ആക്സസ്"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> എന്നതിലെ ഈ ആപ്പിനുള്ള <xliff:g id="PERM">%1$s</xliff:g> ആക്സസ്"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"എല്ലാ <xliff:g id="APP">%1$s</xliff:g> അനുമതികളും കാണുക"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ഈ അനുമതിയുള്ള എല്ലാ ആപ്പുകളും കാണുക"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"സഹായ മൈക്രോഫോൺ ഉപയോഗം കാണിക്കുക"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ഉപയോഗിക്കാത്ത ആപ്പാണെങ്കിൽ അനുമതികൾ നീക്കം ചെയ്യുക"</string> <string name="unused_apps_label" msgid="2595428768404901064">"അനുമതികൾ നീക്കം ചെയ്ത് ഇടം സൃഷ്ടിക്കുക"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"ഉപയോഗിച്ചിട്ടില്ലെങ്കിൽ ആപ്പ് ആക്റ്റിവിറ്റി പോസ് ചെയ്യുക"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ഉപയോഗിക്കാത്തപ്പോൾ ആപ്പ് മാനേജ് ചെയ്യൂ"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"അനുമതികൾ നീക്കം ചെയ്യുക, താൽക്കാലിക ഫയലുകൾ ഇല്ലാതാക്കുക, അറിയിപ്പുകൾ നിർത്തുക"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"അനുമതികൾ നീക്കം ചെയ്യുക, താൽക്കാലിക ഫയലുകൾ ഇല്ലാതാക്കുക, അറിയിപ്പുകൾ നിർത്തുക, ആപ്പ് ആർക്കൈവ് ചെയ്യുക"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"മാസങ്ങളായി ഈ ആപ്പ് ഉപയോഗിക്കുന്നില്ലെങ്കിൽ നിങ്ങളുടെ ഡാറ്റ സംരക്ഷിക്കുന്നതിന്, ഈ ആപ്പിനുള്ള അനുമതികൾ നീക്കം ചെയ്യുന്നതായിരിക്കും."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"കുറച്ച് മാസം ആപ്പ് ഉപയോഗിച്ചില്ലെങ്കിൽ, നിങ്ങളുടെ ഡാറ്റ സംരക്ഷിക്കുന്നതിന്, ഇനിപ്പറയുന്ന അനുമതികൾ നീക്കം ചെയ്യുന്നതായിരിക്കും: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"നിങ്ങളുടെ ഡാറ്റ സംരക്ഷിക്കുന്നതിന്, കുറച്ച് മാസങ്ങളായി ഉപയോഗിക്കാത്ത ആപ്പുകളിൽ നിന്ന് അനുമതികൾ നീക്കം ചെയ്തിരിക്കുന്നു."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"എല്ലാ ഫയലുകളും മാനേജ് ചെയ്യാൻ അനുവദിച്ചവ"</string> <string name="ask_header" msgid="2633816846459944376">"എപ്പോഴും ചോദിക്കുക"</string> <string name="denied_header" msgid="903209608358177654">"അനുവദിച്ചിട്ടില്ല"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> എന്നതിലെ <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"എല്ലാ ഫയലുകളും ആക്സസ് ചെയ്യാൻ കഴിയുന്ന കൂടുതൽ ആപ്പുകൾ കാണുക"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{ഒരു ദിവസം}other{# ദിവസം}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# മണിക്കൂർ}other{# മണിക്കൂർ}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"കുറിപ്പ് ആപ്പ്"</string> <string name="role_notes_description" msgid="8496852798616883551">"നിങ്ങളുടെ ഉപകരണത്തിൽ കുറിപ്പുകൾ രേഖപ്പെടുത്താൻ അനുവദിക്കുന്ന ആപ്പുകൾ"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"കുറിപ്പുകൾ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ഡിഫോൾട്ട് വാലറ്റ് ആപ്പ്"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet ആപ്പ്"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"വ്യത്യസ്ത തരത്തിലുള്ള ഇടപാടുകളിൽ സഹായിക്കുന്നതിന് Wallet ആപ്പുകൾക്ക് നിങ്ങളുടെ ക്രെഡിറ്റ്, ലോയൽറ്റി കാർഡുകൾ, കാർ കീകൾ, മറ്റ് ഇനങ്ങൾ എന്നിവ സംഭരിക്കാൻ കഴിയും."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g>, നിങ്ങളുടെ ഡിഫോൾട്ട് വാലറ്റ് ആപ്പ് ആക്കി സജ്ജീകരിക്കണോ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"അനുമതികളൊന്നും ആവശ്യമില്ല"</string> <string name="request_role_current_default" msgid="738722892438247184">"നിലവിലെ ഡിഫോൾട്ട്"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ഡിഫോൾട്ടായി സജ്ജമാക്കൂ"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ഡാറ്റ പങ്കിടുന്നത് സംബന്ധിച്ച അപ്ഡേറ്റുകൾ"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"നിങ്ങളുടെ ലൊക്കേഷൻ ഡാറ്റ പങ്കിടുന്ന രീതി ചില ആപ്പുകൾ മാറ്റി"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ക്രമീകരണം"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>-ന് ആക്സസ് ചെയ്തു"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"ഇന്നലെ <xliff:g id="TIME_DATE">%1$s</xliff:g>-ന് ആക്സസ് ചെയ്തു"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>-ന് ആക്സസ് ചെയ്തു"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"നിങ്ങളുടെ ഒറ്റത്തവണ പാസ്വേഡ് 132435 ആണ്"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"നിയന്ത്രിത ക്രമീകരണം"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"നിങ്ങളുടെ സുരക്ഷയ്ക്ക്, ഈ ക്രമീകരണം നിലവിൽ ലഭ്യമല്ല."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"ആപ്പിന് <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> എന്നതിലേക്കുള്ള ആക്സസ് നിരസിച്ചു"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"ആപ്പ് സെൻസിറ്റീവ് വിവരങ്ങൾക്കുള്ള അനുമതിയിലേക്ക് ആക്സസ് അഭ്യർത്ഥിച്ചു, ഇത് നിങ്ങളുടെ വ്യക്തിപരവും സാമ്പത്തികവുമായ വിവരങ്ങളെ അപകടത്തിലാക്കിയേക്കാം.<xliff:g id="ID_1"><br><br></xliff:g>ഈ നിയന്ത്രിത അനുമതിയില്ലാതെ ആപ്പ് ശരിയായി പ്രവർത്തിച്ചേക്കില്ല. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ആക്സസ് എങ്ങനെ അനുവദിക്കുന്നുവെന്നറിയുക</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ആപ്പിന് ഡിഫോൾട്ട് <xliff:g id="ROLE_NAME">%1$s</xliff:g> ആകാനുള്ള ആക്സസ് നിരസിച്ചു"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"ആപ്പ് സെൻസിറ്റീവ് വിവരങ്ങൾക്കുള്ള അനുമതികളിലേക്ക് ആക്സസ് അഭ്യർത്ഥിച്ചു, ഇത് നിങ്ങളുടെ വ്യക്തിപരവും സാമ്പത്തികവുമായ വിവരങ്ങളെ അപകടത്തിലാക്കിയേക്കാം.<xliff:g id="ID_1"><br><br></xliff:g>ഈ നിയന്ത്രിത അനുമതികളില്ലാതെ ആപ്പ് ശരിയായി പ്രവർത്തിച്ചേക്കില്ല. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ആക്സസ് എങ്ങനെ അനുവദിക്കുന്നുവെന്നറിയുക</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ആപ്പിന് ആക്സസ് നിരസിച്ചു"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ഈ അനുമതിയിലേക്കുള്ള ആക്സസ് നിങ്ങളുടെ വ്യക്തിപരവും സാമ്പത്തികവുമായ വിവരങ്ങളെ അപകടത്തിലാക്കിയേക്കാം.<xliff:g id="ID_1"><br><br></xliff:g>ഈ നിയന്ത്രിത അനുമതിയില്ലാതെ ആപ്പ് ശരിയായി പ്രവർത്തിച്ചേക്കില്ല. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ആക്സസ് എങ്ങനെ അനുവദിക്കുന്നുവെന്നറിയുക</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"കൂടുതലറിയുക"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ശരി"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"അനുമതി അഭ്യർത്ഥന കാഴ്ച്ചയിൽ നിന്ന് മറച്ചു"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ഈ ആപ്പ് അധിക അനുമതികൾ അഭ്യർത്ഥിക്കുന്നു, എന്നാൽ സ്ട്രീമിംഗ് സെഷനിടയിൽ അനുമതികൾ നൽകാനാകില്ല. ആദ്യം നിങ്ങളുടെ ഫോണിൽ അനുമതി നൽകുക."</string> </resources> diff --git a/PermissionController/res/values-mn-v34/strings.xml b/PermissionController/res/values-mn-v34/strings.xml index fc5ac1818..d8c3fa504 100644 --- a/PermissionController/res/values-mn-v34/strings.xml +++ b/PermissionController/res/values-mn-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Эрүүл мэндийн өгөгдлийн аппын хандалтыг удирдах"</string> <string name="location_settings" msgid="8863940440881290182">"Байршлын хандалт"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Апп болон үйлчилгээнүүдэд. Энэ тохиргоо унтраалттай тохиолдолд таныг яаралтай тусламжийн утасны дугаар луу залгах үед микрофоны өгөгдлийг хуваалцсан хэвээр байж магадгүй"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Апп болон үйлчилгээнүүдэд"</string> </resources> diff --git a/PermissionController/res/values-mn-watch/strings.xml b/PermissionController/res/values-mn-watch/strings.xml index 689766eda..cf4bdf502 100644 --- a/PermissionController/res/values-mn-watch/strings.xml +++ b/PermissionController/res/values-mn-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Өөрчлөх боломжгүй"</string> <string name="generic_yes" msgid="2489207724988649846">"Тийм"</string> <string name="generic_cancel" msgid="2631708607129269698">"Цуцлах"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Үргэлж"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Аппыг ашиглаж байх үед"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Үргэлж"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Аппыг ашиглаж байх үед"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Үргэлж"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Аппыг ашиглаж байх үед"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Үргэлж"</string> </resources> diff --git a/PermissionController/res/values-mn/strings.xml b/PermissionController/res/values-mn/strings.xml index 8896ef931..72976cf5a 100644 --- a/PermissionController/res/values-mn/strings.xml +++ b/PermissionController/res/values-mn/strings.xml @@ -28,7 +28,7 @@ <string name="uninstall_or_disable" msgid="4496612999740858933">"Устгах эсвэл идэвхгүй болгох"</string> <string name="app_not_found_dlg_title" msgid="6029482906093859756">"Апп олдсонгүй"</string> <string name="grant_dialog_button_deny" msgid="88262611492697192">"Бүү зөвшөөр"</string> - <string name="grant_dialog_button_deny_and_dont_ask_again" msgid="1748925431574312595">"Бүү зөвшөөрч, дахин битгий асуу"</string> + <string name="grant_dialog_button_deny_and_dont_ask_again" msgid="1748925431574312595">"Бүү зөвшөөр, дахин бүү асуу"</string> <string name="grant_dialog_button_no_upgrade" msgid="8344732743633736625">"\"Аппыг ашиглаж байх үед\" хэвээр үлдээх"</string> <string name="grant_dialog_button_no_upgrade_one_time" msgid="5125892775684968694">"“Зөвхөн энэ удаад зөвшөөрөх”-г хэвээр хадгалах"</string> <string name="grant_dialog_button_more_info" msgid="213350268561945193">"Дэлгэрэнгүй мэдээлэл"</string> @@ -45,7 +45,7 @@ <string name="permission_add_background_warning_template" msgid="1812914855915092273">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-д <xliff:g id="ACTION">%2$s</xliff:g>-г тогтмол зөвшөөрөх үү?"</string> <string name="allow_permission_foreground_only" msgid="116465816039675404">"Зөвхөн апп ашиглах үед"</string> <string name="allow_permission_always" msgid="5194342531206054051">"Тогтмол"</string> - <string name="deny_permission_deny_and_dont_ask_again" msgid="6106035221490102341">"Бүү зөвшөөрч, дахин битгий асуу"</string> + <string name="deny_permission_deny_and_dont_ask_again" msgid="6106035221490102341">"Бүү зөвшөөр, дахин бүү асуу"</string> <string name="permission_revoked_count" msgid="4785082705441547086">"<xliff:g id="COUNT">%1$d</xliff:g>-г цуцалсан"</string> <string name="permission_revoked_all" msgid="3397649017727222283">"бүгдийг цуцалсан"</string> <string name="permission_revoked_none" msgid="9213345075484381180">"алийг нь ч цуцлаагүй"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Бүх зөвшөөрөл"</string> <string name="other_permissions" msgid="2901186127193849594">"Аппын бусад чадамж"</string> <string name="permission_request_title" msgid="8790310151025020126">"Зөвшөөрлийн хүсэлт"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Андройд Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear-д суулгах/устгах үйлдлийг дэмждэггүй."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-н хандаж болох зүйлсийг сонгоно уу"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-г шинэчилсэн. Энэ аппын хандаж болох зүйлсийг сонгоно уу."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Цуцлах"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Нарийвчилсан байршил унтраалттай үед аппууд таны барагцаалсан байршилд хандах боломжтой"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>-н зөвшөөрөл"</string> <string name="app_permission_header" msgid="2951363137032603806">"Энэ аппын <xliff:g id="PERM">%1$s</xliff:g>-д хандах эрх"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> дээрх энэ аппын <xliff:g id="PERM">%1$s</xliff:g>-д хандах эрх"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g>-н бүх зөвшөөрлийг харах"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Энэ зөвшөөрөлтэй бүх аппыг харах"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Туслах микрофон ашиглалтыг харуулах"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Аппыг ашигладаггүй бол зөвшөөрлийг нь хасах"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Зөвшөөрлийг хасаж, сул зай гаргах"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Ашиглаагүй бол аппын үйл ажиллагааг түр зогсоох"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Хэрэв ашиглаагүй бол аппыг удирдах"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Зөвшөөрлийг хасаж, түр зуурын файлыг устгаж мөн мэдэгдлийг зогсооно"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Зөвшөөрлийг хасаж, түр зуурын файлыг устгаж, мэдэгдлийг зогсоож мөн аппыг архивлана"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Таны өгөгдлийг хамгаалах үүднээс энэ аппыг хэдэн сарын турш ашиглахгүй бол зөвшөөрлийг нь хасах болно."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Таны өгөгдлийг хамгаалах үүднээс аппыг хэдэн сарын турш ашиглахгүй бол дараах зөвшөөрлүүдийг хасах болно: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Таны өгөгдлийг хамгаалах үүднээс таны хэдэн сарын турш ашиглаагүй аппуудын зөвшөөрлийг нь хассан."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Бүх файлыг удирдахыг зөвшөөрсөн"</string> <string name="ask_header" msgid="2633816846459944376">"Тухай бүрд асуух"</string> <string name="denied_header" msgid="903209608358177654">"Зөвшөөрөөгүй"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> дээрх <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Бүх файлд хандах боломжтой бусад аппыг харах"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 өдөр}other{# өдөр}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# цаг}other{# цаг}}"</string> @@ -376,7 +378,7 @@ <string name="role_emergency_request_description" msgid="131645948770262850">"Ямар ч зөвшөөрөл шаардлагагүй"</string> <string name="role_emergency_search_keywords" msgid="1920007722599213358">"ice"</string> <string name="role_home_label" msgid="3871847846649769412">"Нүүр хуудасны өгөгдмөл апп"</string> - <string name="role_home_short_label" msgid="8544733747952272337">"Нүүр хуудасны апп"</string> + <string name="role_home_short_label" msgid="8544733747952272337">"Home апп"</string> <string name="role_home_description" msgid="7997371519626556675">"Таны Android төхөөрөмжийн үндсэн нүүрийг сольдог бөгөөд таны төхөөрөмжийн контент болон онцлогуудад хандах эрх олгодог, ихэвчлэн эхлүүлэгч гэж нэрлэгддэг аппууд"</string> <string name="role_home_request_title" msgid="738136983453341081">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нүүр хуудасны өгөгдмөл аппаар тохируулах уу?"</string> <string name="role_home_request_description" msgid="2658833966716057673">"Ямар ч зөвшөөрөл шаардлагагүй"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Тэмдэглэлийн апп"</string> <string name="role_notes_description" msgid="8496852798616883551">"Таныг төхөөрөмж дээрээ тэмдэглэл хөтлөх боломж олгодог аппууд"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"тэмдэглэл"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Өгөгдмөл түрийвчийн апп"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Түрийвчийн апп"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Төрөл бүрийн гүйлгээнд туслахын тулд түрийвчийн аппууд таны кредит ба лояалти карт, машины түлхүүр болон бусад зүйлийг хадгалах боломжтой."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г таны өгөгдмөл түрийвчийн аппаар тохируулах уу?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Ямар ч зөвшөөрөл шаардлагагүй"</string> <string name="request_role_current_default" msgid="738722892438247184">"Одоогийн өгөгдмөл апп"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Дахиж бүү асуу"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Өгөгдмөлөөр тохируулах"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Өгөгдөл хуваалцах тухай шинэчлэлт"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Зарим апп таны байршлын өгөгдлийг хуваалцдаг аргаа өөрчилсөн"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Тохиргоо"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>-д хандсан"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Өчигдөр <xliff:g id="TIME_DATE">%1$s</xliff:g>-д хандсан"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>-д хандсан"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Таны нэг удаагийн нууц үг бол 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Хязгаарлагдсан тохиргоо"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Таны аюулгүй байдлын үүднээс энэ тохиргоо одоогоор боломжгүй байна."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Аппын <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>-д хандах эрхээс татгалзсан"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Апп нь таны хувийн болон санхүүгийн мэдээллийг эрсдэлд оруулж болох эмзэг зөвшөөрөлд хандах эрх хүссэн.<xliff:g id="ID_1"><br><br></xliff:g>Энэ хязгаарлагдмал зөвшөөрөлгүйгээр уг апп зохих ёсоор ажиллахгүй байх боломжтой. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Хандах эрхийг хэрхэн зөвшөөрөх талаар мэдэж авах</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Аппын өгөгдмөл <xliff:g id="ROLE_NAME">%1$s</xliff:g> болох хандах эрхээс татгалзсан"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Апп нь таны хувийн болон санхүүгийн мэдээллийг эрсдэлд оруулж болох эмзэг зөвшөөрлүүдэд хандах эрх хүссэн.<xliff:g id="ID_1"><br><br></xliff:g>Эдгээр хязгаарлагдмал зөвшөөрөлгүйгээр уг апп зохих ёсоор ажиллахгүй байх боломжтой. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Хандах эрхийг хэрхэн зөвшөөрөх талаар мэдэж авах</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Аппын хандах эрхээс татгалзсан"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Энэ зөвшөөрөлд хандах эрх нь таны хувийн болон санхүүгийн мэдээллийг эрсдэлд оруулж болно.<xliff:g id="ID_1"><br><br></xliff:g>Энэ хязгаарлагдмал зөвшөөрөлгүйгээр уг апп зохих ёсоор ажиллахгүй байх боломжтой. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Хандах эрхийг хэрхэн зөвшөөрөх талаар мэдэж авах</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Нэмэлт мэдээлэл авах"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ОК"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Зөвшөөрлийн хүсэлтийг зогсоосон"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Энэ апп нэмэлт зөвшөөрөл хүсэж байгаа ч дамжуулалтын харилцан үйлдлийн үеэр зөвшөөрөл олгох боломжгүй. Эхлээд утсан дээрээ зөвшөөрөл олгоно уу."</string> </resources> diff --git a/PermissionController/res/values-mr-v34/strings.xml b/PermissionController/res/values-mr-v34/strings.xml index 8c9152379..e130cff40 100644 --- a/PermissionController/res/values-mr-v34/strings.xml +++ b/PermissionController/res/values-mr-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"आरोग्यविषयक डेटासंबंधित अॅपचा अॅक्सेस व्यवस्थापित करा"</string> <string name="location_settings" msgid="8863940440881290182">"स्थान अॅक्सेस"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ॲप्स आणि सेवांसाठी. हे सेटिंग बंद असल्यास, तुम्ही आणीबाणी नंबरवर कॉल करता, तेव्हा मायक्रोफोन डेटा तरीही शेअर केला जाऊ शकतो"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ॲप्स आणि सेवांसाठी"</string> </resources> diff --git a/PermissionController/res/values-mr-watch/strings.xml b/PermissionController/res/values-mr-watch/strings.xml index 474ea9d82..77d7ee44a 100644 --- a/PermissionController/res/values-mr-watch/strings.xml +++ b/PermissionController/res/values-mr-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"बदलू शकत नाही"</string> <string name="generic_yes" msgid="2489207724988649846">"होय"</string> <string name="generic_cancel" msgid="2631708607129269698">"रद्द करा"</string> + <string name="permission_access_always" msgid="2107115233573823032">"पूर्ण वेळ"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"अॅप वापरताना"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"पूर्ण वेळ"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"अॅप वापरताना"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"पूर्ण वेळ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"अॅप वापरताना"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"पूर्ण वेळ"</string> </resources> diff --git a/PermissionController/res/values-mr/strings.xml b/PermissionController/res/values-mr/strings.xml index f8757e5cf..aec1cd3d7 100644 --- a/PermissionController/res/values-mr/strings.xml +++ b/PermissionController/res/values-mr/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"सर्व परवानग्या"</string> <string name="other_permissions" msgid="2901186127193849594">"अन्य अॅप क्षमता"</string> <string name="permission_request_title" msgid="8790310151025020126">"परवानगीची विनंती"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"इंस्टॉल करा/अनइंस्टॉल करा क्रिया Wear वर सपोर्ट करत नाहीत."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला काय अॅक्सेस करण्याची परवानगी द्यावी ते निवडा"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> अपडेट केले गेले आहे. या ॲपला काय अॅक्सेस करण्याची परवानगी द्यावी ते निवडा."</string> <string name="review_button_cancel" msgid="2191147944056548886">"रद्द करा"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"अचूक स्थान बंद असते, तेव्हा ॲप्स तुमचे अंदाजे स्थान अॅक्सेस करू शकतात"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> परवानगी"</string> <string name="app_permission_header" msgid="2951363137032603806">"या अॅपसाठी <xliff:g id="PERM">%1$s</xliff:g> अॅक्सेस द्या"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"या अॅपसाठी <xliff:g id="DEVICE_NAME">%2$s</xliff:g> वरील <xliff:g id="PERM">%1$s</xliff:g> चा अॅक्सेस"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"सर्व <xliff:g id="APP">%1$s</xliff:g> परवानग्या पहा"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ही परवानगी असलेली सर्व अॅप्स पहा"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistant ने मायक्रोफोनचा केलेला वापर दाखवा"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"अॅप वापरले नसल्यास, परवानग्या काढून टाका"</string> <string name="unused_apps_label" msgid="2595428768404901064">"परवानग्या काढा आणि जागा मोकळी करा"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"न वापरल्यास अॅप अॅक्टिव्हिटी थांबवा"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"वापरले नसल्यास ॲप व्यवस्थापित करा"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"परवानग्या काढून टाका, तात्पुरत्या फाइल हटवा आणि सूचना थांबवा"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"परवानग्या काढून टाका, तात्पुरत्या फाइल हटवा, सूचना थांबवा आणि ॲप संग्रहित करा"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"तुमच्या डेटाचे संरक्षण करण्यासाठी, अॅप काही महिन्यांत वापरले गेले नसल्यास, या अॅपच्या परवानग्या काढल्या जातील."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"तुमच्या डेटाचे संरक्षण करण्यासाठी, अॅप काही महिन्यांत वापरले गेले नसल्यास, पुढील परवानग्या काढल्या जातील: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"तुमच्या डेटाचे संरक्षण करण्यासाठी, तुम्ही काही महिन्यांत न वापरलेल्या ॲप्समधून परवानग्या काढल्या गेल्या आहेत."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"सर्व फाइल व्यवस्थापित करण्यास अनुमती दिली आहे"</string> <string name="ask_header" msgid="2633816846459944376">"प्रत्येक वेळी विचारा"</string> <string name="denied_header" msgid="903209608358177654">"अनुमती नाही"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> वरील <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"सर्व फाइलचा ॲक्सेस असलेली आणखी ॲप्स पहा"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{एक दिवस}other{# दिवस}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# तास}other{# तास}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"टिपांचे अॅप"</string> <string name="role_notes_description" msgid="8496852798616883551">"तुमच्या डिव्हाइसवर तुम्हाला टिपा घेण्याची अनुमती देणारी अॅप्स"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"टिपा"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"डीफॉल्ट वॉलेट अॅप"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"वॉलेट अॅप"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"वॉलेट ॲप्स ही तुमची क्रेडिट आणि लॉयल्टी कार्ड, कार की व विविध प्रकारच्या व्यवहारांमध्ये मदत करण्यासाठी इतर गोष्टी स्टोअर करू शकतात."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमचे डीफॉल्ट वॉलेट ॲप म्हणून सेट करायचे आहे का?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"कोणत्याही परवानगीची आवश्यकता नाही"</string> <string name="request_role_current_default" msgid="738722892438247184">"सद्य डीफॉल्ट"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"पुन्हा विचारू नका"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"डीफॉल्ट सेट करा"</string> @@ -581,7 +588,7 @@ <string name="recent_app_usage_1_qs" msgid="261450184773310741">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) द्वारे अलीकडे वापरले गेले"</string> <string name="active_app_usage_2_qs" msgid="6107866785243565283">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) द्वारे वापरले जात आहे"</string> <string name="recent_app_usage_2_qs" msgid="3591205954235694403">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) द्वारे अलीकडे वापरले गेले"</string> - <string name="media_confirm_dialog_positive_button" msgid="9020793594051526399">"कंफर्म करा"</string> + <string name="media_confirm_dialog_positive_button" msgid="9020793594051526399">"कन्फर्म करा"</string> <string name="media_confirm_dialog_negative_button" msgid="226987376924861785">"मागे जा"</string> <string name="media_confirm_dialog_title_a_to_p_aural_allow" msgid="8560601114044699903">"इतर फाइलच्या अॅक्सेसलादेखील अनुमती दिली जाईल"</string> <string name="media_confirm_dialog_title_a_to_p_aural_deny" msgid="7841428716317307685">"इतर फाइलच्या अॅक्सेसलादेखील अनुमती दिली जाणार नाही"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"डेटा शेअरिंगचे अपडेट"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"काही अॅप्सनी तुमचा स्थान डेटा शेअर करण्याची त्यांची पद्धत बदलली"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"सेटिंग्ज"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> वाजता ॲक्सेस केले"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"काल <xliff:g id="TIME_DATE">%1$s</xliff:g> वाजता ॲक्सेस केले"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> ला <xliff:g id="TIME_DATE_1">%2$s</xliff:g> वाजता ॲक्सेस केले"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"तुमचा वन टाइम पासवर्ड १३२४३५ हा आहे"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"प्रतिबंधित सेटिंग"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"तुमच्या सुरक्षेसाठी, हे सेटिंग सध्या उपलब्ध नाही."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"अॅपचा <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> साठीचा अॅक्सेस नाकारला गेला आहे"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"ॲपने संवेदनशील परवानगीसाठी अॅक्सेसची विनंती केली आहे, ज्यामुळे तुमची वैयक्तिक आणि आर्थिक माहिती धोक्यात येऊ शकते.<xliff:g id="ID_1"><br><br></xliff:g>या प्रतिबंधित परवानगीशिवाय ॲप कदाचित योग्यरीत्या काम करणार नाही. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>अॅक्सेसला अनुमती कशी द्यावी हे जाणून घ्या</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"अॅपचा डीफॉल्ट <xliff:g id="ROLE_NAME">%1$s</xliff:g> असण्यासाठीचा अॅक्सेस नाकारला गेला आहे"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"ॲपने संवेदनशील परवानग्यांसाठी अॅक्सेसची विनंती केली आहे, ज्यामुळे तुमची वैयक्तिक आणि आर्थिक माहिती धोक्यात येऊ शकते.<xliff:g id="ID_1"><br><br></xliff:g>या प्रतिबंधित परवानग्यांशिवाय ॲप कदाचित योग्यरीत्या काम करणार नाही. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>अॅक्सेसला अनुमती कशी द्यावी हे जाणून घ्या</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"अॅपचा अॅक्सेस नाकारला गेला आहे"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"या परवानगीच्या अॅक्सेसमुळे तुमची वैयक्तिक आणि आर्थिक माहिती धोक्यात येऊ शकते.<xliff:g id="ID_1"><br><br></xliff:g>या प्रतिबंधित परवानगीशिवाय ॲप कदाचित योग्यरित्या काम करणार नाही. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>अॅक्सेसला अनुमती कशी द्यावी हे जाणून घ्या</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"अधिक जाणून घ्या"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ओके"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"परवानगी मागणारी विनंती सप्रेस केली आहे"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"हे ॲप अतिरिक्त परवानग्यांची विनंती करत आहे, पण स्ट्रीमिंग सेशनदरम्यान परवानग्या दिल्या जाऊ शकत नाहीत. आधी तुमच्या फोनवर परवानगी द्या."</string> </resources> diff --git a/PermissionController/res/values-ms-v34/strings.xml b/PermissionController/res/values-ms-v34/strings.xml index 6fd21c7af..b544d95d0 100644 --- a/PermissionController/res/values-ms-v34/strings.xml +++ b/PermissionController/res/values-ms-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Urus akses apl kepada data kesihatan"</string> <string name="location_settings" msgid="8863940440881290182">"Akses lokasi"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Untuk apl dan perkhidmatan. Jika tetapan ini dimatikan, data mikrofon mungkin masih dikongsi apabila anda memanggil nombor kecemasan"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Untuk apl dan perkhidmatan"</string> </resources> diff --git a/PermissionController/res/values-ms-watch/strings.xml b/PermissionController/res/values-ms-watch/strings.xml index f762231d0..9791f6df8 100644 --- a/PermissionController/res/values-ms-watch/strings.xml +++ b/PermissionController/res/values-ms-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Tidak dpt diubah"</string> <string name="generic_yes" msgid="2489207724988649846">"Ya"</string> <string name="generic_cancel" msgid="2631708607129269698">"Batal"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Sepanjang masa"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Semasa menggunakan apl"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Sepanjang masa"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Semasa menggunakan apl"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Sepanjang masa"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Semasa menggunakan apl"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Sepanjang masa"</string> </resources> diff --git a/PermissionController/res/values-ms/strings.xml b/PermissionController/res/values-ms/strings.xml index a2e48b2bd..5a320b25e 100644 --- a/PermissionController/res/values-ms/strings.xml +++ b/PermissionController/res/values-ms/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Semua kebenaran"</string> <string name="other_permissions" msgid="2901186127193849594">"Keupayaan apl lain"</string> <string name="permission_request_title" msgid="8790310151025020126">"Permintaan kebenaran"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Tindakan pasang/nyahpasang tidak disokong pada Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Pilih perkara yang boleh diakses oleh <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> telah dikemas kini. Pilih perkara yang boleh diakses oleh apl ini."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Batal"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Apabila lokasi tepat dimatikan, apl boleh mengakses lokasi anggaran anda"</string> <string name="app_permission_title" msgid="2090897901051370711">"Kebenaran <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Akses <xliff:g id="PERM">%1$s</xliff:g> untuk apl ini"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"akses <xliff:g id="PERM">%1$s</xliff:g> untuk apl ini pada <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Lihat semua kebenaran <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Lihat semua apl dengan kebenaran ini"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Tunjukkan penggunaan mikrofon pembantu"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Alih keluar kebenaran jika apl tidak digunakan"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Alih keluar kebenaran dan kosongkan ruang"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Jeda aktiviti apl jika tidak digunakan"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Urus apl jika tidak digunakan"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Alih keluar kebenaran, padamkan fail sementara dan hentikan pemberitahuan"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Alih keluar kebenaran, padamkan fail sementara, hentikan pemberitahuan dan arkibkan apl tersebut"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Untuk melindungi data anda, kebenaran apl ini akan dialih keluar jika apl tidak digunakan selama beberapa bulan."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Untuk melindungi data anda, jika apl tidak digunakan selama beberapa bulan, kebenaran berikut akan dialih keluar: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Untuk melindungi data anda, kebenaran telah dialih keluar daripada apl yang tidak anda gunakan selama beberapa bulan."</string> @@ -249,11 +250,12 @@ <string name="app_permission_never_accessed_denied_summary" msgid="6596000497490905146">"Ditolak / Tidak pernah mengakses"</string> <string name="allowed_header" msgid="7769277978004790414">"Dibenarkan"</string> <string name="allowed_always_header" msgid="6455903312589013545">"Dibenarkan sepanjang masa"</string> - <string name="allowed_foreground_header" msgid="6845655788447833353">"Dibenarkan hanya semasa dalam penggunaan"</string> + <string name="allowed_foreground_header" msgid="6845655788447833353">"Dibenarkan hanya semasa digunakan"</string> <string name="allowed_storage_scoped" msgid="5383645873719086975">"Dibenarkan mengakses media sahaja"</string> <string name="allowed_storage_full" msgid="5356699280625693530">"Dibenarkan mengurus semua fail"</string> <string name="ask_header" msgid="2633816846459944376">"Tanya setiap kali"</string> <string name="denied_header" msgid="903209608358177654">"Tidak dibenarkan"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> pada <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Lihat lagi apl yang boleh mengakses semua fail"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 hari}other{# hari}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# jam}other{# jam}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Apl nota"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apl yang membolehkan anda mengambil nota pada peranti anda"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"nota"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Apl dompet lalai"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Apl dompet"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Apl dompet boleh menyimpan kad kredit dan kesetiaan anda, kunci kereta dan perkara lain untuk membantu pelbagai bentuk transaksi."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Tetapkan <xliff:g id="APP_NAME">%1$s</xliff:g> sebagai apl dompet lalai anda?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Kebenaran tidak diperlukan"</string> <string name="request_role_current_default" msgid="738722892438247184">"Lalai semasa"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Jangan tanya lagi"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Tetapkan sbg lalai"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mengakses kenalan anda?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mengakses kenalan anda pada <b><xliff:g id="DEVICE">%2$s</xliff:g></b> anda?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mengakses lokasi peranti ini?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mengakses lokasi <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>s</b> anda?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mengakses lokasi <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> anda?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Apl ini hanya dapat mengakses lokasi semasa anda menggunakan apl tersebut"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mengakses lokasi peranti ini?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mengakses lokasi <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g> anda?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Kemaskinian perkongsian data"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Sesetengah apl mengubah cara apl itu boleh berkongsi data lokasi anda"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Tetapan"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Diakses <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Diakses semalam <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Diakses <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Kata laluan sekali guna anda ialah 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Tetapan terhad"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Untuk keselamatan anda, tetapan ini tidak tersedia pada masa ini."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Akses apl kepada <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> telah ditolak"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Apl meminta akses kepada kebenaran sensitif yang boleh mengakibatkan risiko terhadap maklumat peribadi dan kewangan anda.<xliff:g id="ID_1"><br><br></xliff:g>Apl tersebut mungkin tidak dapat berfungsi dengan betul tanpa kebenaran terhad ini. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ketahui cara membenarkan akses</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Akses apl untuk menjadi <xliff:g id="ROLE_NAME">%1$s</xliff:g> secara lalai telah ditolak"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Apl meminta akses kepada kebenaran sensitif yang boleh mengakibatkan risiko terhadap maklumat peribadi dan kewangan anda.<xliff:g id="ID_1"><br><br></xliff:g>Apl tersebut mungkin tidak dapat berfungsi dengan betul tanpa kebenaran terhad ini. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ketahui cara membenarkan akses</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Akses apl telah ditolak"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Akses kepada kebenaran ini b boleh mengakibatkan risiko terhadap maklumat peribadi dan kewangan anda.<xliff:g id="ID_1"><br><br></xliff:g>Apl tersebut mungkin tidak dapat berfungsi dengan betul tanpa kebenaran terhad ini. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ketahui cara membenarkan akses</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Ketahui lebih lanjut"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Permintaan kebenaran disekat"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Apl ini meminta kebenaran tambahan tetapi kebenaran tidak boleh diberikan dalam sesi penstriman. Berikan kebenaran pada telefon anda dahulu."</string> </resources> diff --git a/PermissionController/res/values-my-v34/strings.xml b/PermissionController/res/values-my-v34/strings.xml index 4d4e03401..965a92df2 100644 --- a/PermissionController/res/values-my-v34/strings.xml +++ b/PermissionController/res/values-my-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ကျန်းမာရေးဒေတာအတွက် အက်ပ်သုံးခွင့်ကို စီမံနိုင်သည်"</string> <string name="location_settings" msgid="8863940440881290182">"တည်နေရာသုံးခွင့်"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"အက်ပ်နှင့် ဝန်ဆောင်မှုများအတွက်။ ဤဆက်တင်ကို ပိတ်ထားသော်လည်း အရေးပေါ် နံပါတ်ကို သင်ခေါ်ဆိုချိန်တွင် မိုက်ခရိုဖုန်းဒေတာ မျှဝေနိုင်သေးသည်"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"အက်ပ်နှင့် ဝန်ဆောင်မှုများအတွက်"</string> </resources> diff --git a/PermissionController/res/values-my-watch/strings.xml b/PermissionController/res/values-my-watch/strings.xml index 6486ae7ff..cd9159fa6 100644 --- a/PermissionController/res/values-my-watch/strings.xml +++ b/PermissionController/res/values-my-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ပြောင်းလဲ မရနိုင်ပါ"</string> <string name="generic_yes" msgid="2489207724988649846">"Yes"</string> <string name="generic_cancel" msgid="2631708607129269698">"မလုပ်တော့"</string> + <string name="permission_access_always" msgid="2107115233573823032">"အချိန်တိုင်း"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"အက်ပ်ကို သုံးနေစဉ်"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"အချိန်တိုင်း"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"အက်ပ်ကို သုံးနေစဉ်"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"အချိန်တိုင်း"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"အက်ပ်ကို သုံးနေစဉ်"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"အချိန်တိုင်း"</string> </resources> diff --git a/PermissionController/res/values-my/strings.xml b/PermissionController/res/values-my/strings.xml index cd68ad6e1..e3512dc35 100644 --- a/PermissionController/res/values-my/strings.xml +++ b/PermissionController/res/values-my/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ခွင့်ပြုချက် အားလုံး"</string> <string name="other_permissions" msgid="2901186127193849594">"အခြားအက်ပ်၏ စွမ်းရည်များ"</string> <string name="permission_request_title" msgid="8790310151025020126">"ခွင့်ပြုချက် တောင်းခံမှု"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear ပေါ်တွင် ထည့်သွင်းခြင်း/ဖြုတ်ခြင်းများကို ပံ့ပိုးမထားပါ။"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"&It;b7gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&It;/b> က အသုံးပြုခွင့်ရမည့် အရာတို့ကို ရွေးပါ"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"&It;b><xliff:g id="APP_NAME">%1$s</xliff:g>&It;/b> ကို အပ်ဒိတ်လုပ်ပြီးပါပြီ။ ဤအက်ပ်က အသုံးပြုခွင့်ရမည့်အရာတို့ကို ရွေးပါ။"</string> <string name="review_button_cancel" msgid="2191147944056548886">"မလုပ်တော့"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"နေရာအတိအကျကို ပိတ်ထားသည့်အခါ အက်ပ်များက သင်၏တည်နေရာခန့်မှန်းခြေကို သုံးနိုင်သည်"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> ခွင့်ပြုချက်"</string> <string name="app_permission_header" msgid="2951363137032603806">"ဤအက်ပ်အတွက် <xliff:g id="PERM">%1$s</xliff:g> အသုံးပြုခွင့်"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> တွင် ဤအက်ပ်အတွက် <xliff:g id="PERM">%1$s</xliff:g> သုံးခွင့်"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g> ခွင့်ပြုချက်အားလုံး ကြည့်ရန်"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ဤခွင့်ပြုချက်ရှိသော အက်ပ်အားလုံးကို ကြည့်ရန်"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistant မိုက်ကရိုဖုန်း အသုံးပြုမှုကို ပြပါ"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"အက်ပ်ကိုအသုံးမပြုလျှင် ခွင့်ပြုချက်များ ဖယ်ရှားရန်"</string> <string name="unused_apps_label" msgid="2595428768404901064">"ခွင့်ပြုချက်များဖယ်ရှားပြီး နေရာလွတ်ပြုလုပ်ရန်"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"အသုံးမပြုပါက အက်ပ်လုပ်ဆောင်ချက် ခဏရပ်ရန်"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"အသုံးမပြုပါက အက်ပ်ကို စီမံရန်"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ခွင့်ပြုချက် ဖယ်ရှားခြင်း၊ ယာယီဖိုင် ဖျက်ခြင်း၊ အကြောင်းကြားချက် ရပ်ခြင်း"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ခွင့်ပြုချက်များ ဖယ်ရှားခြင်း၊ ယာယီဖိုင်များ ဖျက်ခြင်း၊ အကြောင်းကြားချက်များ ရပ်ခြင်းနှင့် အက်ပ်သိမ်းခြင်းတို့ ပြုလုပ်နိုင်သည်"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"အက်ပ်ကို လအနည်းငယ် အသုံးမပြုပါက သင်၏ဒေတာကိုကာကွယ်ရန် ဤအက်ပ်အတွက် ခွင့်ပြုချက်များကို ဖယ်ရှားပါမည်။"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"အက်ပ်ကို လအနည်းငယ် အသုံးမပြုပါက သင်၏ဒေတာကိုကာကွယ်ရန် အောက်ပါခွင့်ပြုချက်များကို ဖယ်ရှားပါမည်- <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"သင်၏ဒေတာကိုကာကွယ်ရန် လအနည်းငယ်အတွင်း အသုံးမပြုသော အက်ပ်များမှ ခွင့်ပြုချက်များကို ဖယ်ရှားလိုက်သည်။"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ဖိုင်အားလုံးကို စီမံခွင့်ပြုထားသည်"</string> <string name="ask_header" msgid="2633816846459944376">"အမြဲမေးရန်"</string> <string name="denied_header" msgid="903209608358177654">"ခွင့်ပြုမထားပါ"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> ရှိ <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ဖိုင်အားလုံးသုံးနိုင်သည့် နောက်ထပ်အက်ပ်များ ကြည့်ရန်"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ရက်}other{# ရက်}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# နာရီ}other{# နာရီ}}"</string> @@ -349,8 +351,8 @@ <string name="accessibility_service_dialog_title_multiple" msgid="5527879210683548175">"အများသုံးစွဲနိုင်မှုဆိုင်ရာ အက်ပ် <xliff:g id="NUM_SERVICES">%s</xliff:g> ခုက သင့်စက်ပစ္စည်းကို အပြည့်အဝ အသုံးပြုခွင့်ရှိသည်"</string> <string name="accessibility_service_dialog_bottom_text_single" msgid="1128666197822205958">"<xliff:g id="SERVICE_NAME">%s</xliff:g> သည် သင်၏ မျက်နှာပြင်၊ လုပ်ဆောင်ချက်များ၊ ထည့်သွင်းမှုများကို ကြည့်နိုင်ပြီး လုပ်ဆောင်ချက်များကို ဆောင်ရွက်နိုင်သည့်အပြင် မျက်နှာပြင်သမှုကိုလည်း ထိန်းချုပ်နိုင်သည်။"</string> <string name="accessibility_service_dialog_bottom_text_multiple" msgid="7009848932395519852">"ဤအက်ပ်များက သင်၏ မျက်နှာပြင်၊ လုပ်ဆောင်ချက်များ၊ ထည့်သွင်းမှုများကို ကြည့်နိုင်ပြီး လုပ်ဆောင်ချက်များကို ဆောင်ရွက်နိုင်သည့်အပြင် မျက်နှာပြင်ပြသမှုကိုလည်း ထိန်းချုပ်နိုင်သည်။"</string> - <string name="role_assistant_label" msgid="4727586018198208128">"မူလဒစ်ဂျစ်တယ် Assistant အက်ပ်"</string> - <string name="role_assistant_short_label" msgid="3369003713187703399">"ဒစ်ဂျစ်တယ် Assistant အက်ပ်"</string> + <string name="role_assistant_label" msgid="4727586018198208128">"မူရင်း ဒစ်ဂျစ်တယ်အထောက်အကူ အက်ပ်"</string> + <string name="role_assistant_short_label" msgid="3369003713187703399">"ဒစ်ဂျစ်တယ်အထောက်အကူ အက်ပ်"</string> <string name="role_assistant_description" msgid="6622458130459922952">"အကူအညီအက်ပ်များသည် သင်ကြည့်နေသည့် မျက်နှာပြင်မှ အချက်အလက်ကို အခြေခံ၍ ပံ့ပိုးပေးနိုင်ပါသည်။ ဘက်စုံ အထောက်အကူပေးနိုင်ရန်အတွက် အချို့အက်ပ်များသည် စဖွင့်စနစ်နှင့် အသံဖြင့်ထည့်သွင်းဝန်ဆောင်မှု နှစ်ခုလုံးကို ပံ့ပိုးပါသည်။"</string> <string name="role_browser_label" msgid="2877796144554070207">"မူရင်း ဘရောင်ဇာအက်ပ်"</string> <string name="role_browser_short_label" msgid="6745009127123292296">"ဘရောင်ဇာ အက်ပ်"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"မှတ်စုရေးသောအက်ပ်"</string> <string name="role_notes_description" msgid="8496852798616883551">"စက်ပစ္စည်းတွင် မှတ်စုရေးခွင့်ပြုသော အက်ပ်များ"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"မှတ်စုများ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"မူရင်း Wallet အက်ပ်"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet အက်ပ်"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Wallet အက်ပ်များသည် ငွေလွှဲပြောင်းသည့် ဖောင်အမျိုးမျိုးနှင့်ပတ်သက်ပြီး ကူညီရန် သင်၏ခရက်ဒစ်ကတ်၊ ဖောက်သည်ကတ်များ၊ ကားသော့နှင့် အခြားအရာများကို သိမ်းနိုင်သည်။"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို သင်၏မူရင်း Wallet အက်ပ်အဖြစ် သတ်မှတ်မလား။"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ခွင့်ပြုချက် မလိုပါ"</string> <string name="request_role_current_default" msgid="738722892438247184">"လက်ရှိ မူရင်း"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ထပ်မမေးပါနှင့်"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"မူရင်း သတ်မှတ်ရန်"</string> @@ -460,7 +467,7 @@ <string name="permgrouprequest_device_aware_storage_isolated" msgid="5934218468708513375">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> ရှိ ဓာတ်ပုံနှင့် မီဒီယာများကို သုံးခွင့်ပြုမလား။"</string> <string name="permgrouprequest_contacts" msgid="8391550064551053695">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏အဆက်အသွယ်များကို သုံးခွင့်ပေးလိုပါသလား။"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> တွင် သင့်အဆက်အသွယ်များ သုံးခွင့်ပြုမလား။"</string> - <string name="permgrouprequest_location" msgid="6990232580121067883">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား ဤစက်ပစ္စည်း၏တည်နေရာကို သုံးခွင့်ပေးလိုပါသလား။"</string> + <string name="permgrouprequest_location" msgid="6990232580121067883">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား ဤစက်ပစ္စည်း၏တည်နေရာကို သုံးခွင့်ပေးမလား။"</string> <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင့် <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g> ၏ </b> တည်နေရာ သုံးခွင့်ပြုမလား။"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"အက်ပ်ကိုအသုံးပြုသည့် အချိန်တွင်သာ ၎င်းကတည်နေရာကို အသုံးပြုခွင့်ရပါမည်"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား ဤစက်ပစ္စည်း၏တည်နေရာကို သုံးခွင့်ပေးလိုပါသလား။"</string> @@ -495,7 +502,7 @@ <string name="permgrouprequest_microphone" msgid="2825208549114811299">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို အသံဖမ်းယူခွင့် ပေးလိုပါသလား။"</string> <string name="permgrouprequest_device_aware_microphone" msgid="1266843551173029370">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင့် <b><xliff:g id="DEVICE">%2$s</xliff:g></b> တွင် အသံဖမ်းယူခွင့်ပြုမလား။"</string> <string name="permgrouprequestdetail_microphone" msgid="8510456971528228861">"ဤအက်ပ်ကို အသုံးပြုနေသည့် အချိန်တွင်သာ ၎င်းက အသံဖမ်းနိုင်သည်။"</string> - <string name="permgroupbackgroundrequest_microphone" msgid="8874462606796368183">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို အသံဖမ်းခွင့် ပေးလိုပါသလား။"</string> + <string name="permgroupbackgroundrequest_microphone" msgid="8874462606796368183">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို အသံဖမ်းခွင့် ပေးမလား။"</string> <string name="permgroupbackgroundrequest_device_aware_microphone" msgid="4990337225146130185">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင့် <b><xliff:g id="DEVICE">%2$s</xliff:g></b> တွင် အသံဖမ်းယူခွင့်ပြုမလား။"</string> <string name="permgroupbackgroundrequestdetail_microphone" msgid="553702902263681838">"ဤအက်ပ်ကို သင်အသုံးမပြုနေလျှင်ပင် ၎င်းက တစ်ချိန်လုံး အသံဖမ်းယူလိုသည်။ "<annotation id="link">"ဆက်တင်များတွင် ခွင့်ပြုပါ။"</annotation></string> <string name="permgroupupgraderequest_microphone" msgid="1362781696161233341">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b&gt အတွက် မိုက်ခရိုဖုန်း အသုံးပြုခွင့် ပြောင်းမလား။"</string> @@ -503,10 +510,10 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"ဤအက်ပ်ကို သင်အသုံးမပြုနေလျှင်ပင် ၎င်းက တစ်ချိန်လုံး အသံဖမ်းလိုသည်။ "<annotation id="link">"ဆက်တင်များတွင် ခွင့်ပြုပါ။"</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင့်ကိုယ်ခန္ဓာလှုပ်ရှားမှုကို ဝင်ကြည့်ခွင့် ပေးလိုပါသလား။"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> တွင် သင့်ကိုယ်ခန္ဓာလှုပ်ရှားမှု သုံးခွင့်ပြုမလား။"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား ဓာတ်ပုံနှင့် ဗီဒီယိုရိုက်ကူးခွင့် ပေးလိုပါသလား။"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား ဓာတ်ပုံနှင့် ဗီဒီယိုရိုက်ကူးခွင့် ပေးမလား။"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> တွင် ဓာတ်ပုံနှင့် ဗီဒီယိုရိုက်ကူးခွင့်ပြုမလား။"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"ဤအက်ပ်ကို အသုံးပြုနေသည့် အချိန်တွင်သာ ၎င်းက ဓာတ်ပုံနှင့် ဗီဒီယိုများကို ရိုက်ကူးနိုင်သည်။"</string> - <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို ဓာတ်ပုံနှင့် ဗီဒီယိုရိုက်ကူးခွင့် ပေးလိုပါသလား။"</string> + <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို ဓာတ်ပုံနှင့် ဗီဒီယိုရိုက်ကူးခွင့် ပေးမလား။"</string> <string name="permgroupbackgroundrequest_device_aware_camera" msgid="6718286540040964849">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> တွင် ဓာတ်ပုံနှင့် ဗီဒီယိုရိုက်ကူးခွင့်ပြုမလား။"</string> <string name="permgroupbackgroundrequestdetail_camera" msgid="4458783509089859078">"ဤအက်ပ်ကို သင်အသုံးမပြုနေလျှင်ပင် ၎င်းက ဓာတ်ပုံနှင့် ဗီဒီယိုများကို တစ်ချိန်လုံး ရိုက်ကူးလိုသည်။ "<annotation id="link">"ဆက်တင်များတွင် ခွင့်ပြုပါ။"</annotation></string> <string name="permgroupupgraderequest_camera" msgid="640758449200241582">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b&gt အတွက် ကင်မရာအသုံးပြုခွင့် ပြောင်းမလား။"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ဒေတာမျှဝေခြင်း အပ်ဒိတ်"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"အက်ပ်အချို့သည် ၎င်းတို့က သင်၏ တည်နေရာဒေတာ မျှဝေနိုင်သော နည်းလမ်းကို ပြောင်းထားသည်"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ဆက်တင်များ"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> တွင် ဝင်ကြည့်ထားသည်"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"မနေ့ <xliff:g id="TIME_DATE">%1$s</xliff:g> တွင် ဝင်ကြည့်ထားသည်"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g><xliff:g id="TIME_DATE_1">%2$s</xliff:g> တွင် ဝင်ကြည့်ထားသည်"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"သင့်တစ်ခါသုံး စကားဝှက်သည် 132435 ဖြစ်သည်"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"ကန့်သတ်ဆက်တင်"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"သင့်လုံခြုံရေးအတွက် ဤဆက်တင်ကို လောလောဆယ် မရနိုင်ပါ။"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"အက်ပ်ကို <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> သုံးခွင့် ငြင်းပယ်ထားသည်"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"အက်ပ်သည် သင်၏ ပုဂ္ဂိုလ်ရေးနှင့် ငွေကြေးဆိုင်ရာ အချက်အလက်များကို အန္တရာယ်ဖြစ်စေနိုင်သော သတိထားရမည့် ခွင့်ပြုချက်သုံးရန် တောင်းဆိုထားသည်။<xliff:g id="ID_1"><br><br></xliff:g>အက်ပ်သည် ဤကန့်သတ်ထားသော ခွင့်ပြုချက်မရှိပါက ကောင်းစွာမလုပ်ဆောင်ခြင်း ဖြစ်နိုင်သည်။ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>သုံးခွင့်ပြုနည်းကို လေ့လာရန်</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"အက်ပ်အား မူရင်း <xliff:g id="ROLE_NAME">%1$s</xliff:g> အဖြစ် လုပ်ဆောင်ခွင့် ငြင်းပယ်ထားသည်"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"အက်ပ်သည် သင်၏ ပုဂ္ဂိုလ်ရေးနှင့် ငွေကြေးဆိုင်ရာ အချက်အလက်များကို အန္တရာယ်ဖြစ်စေနိုင်သော သတိထားရမည့် ခွင့်ပြုချက်များသုံးရန် တောင်းဆိုထားသည်။<xliff:g id="ID_1"><br><br></xliff:g>အက်ပ်သည် ဤကန့်သတ်ထားသော ခွင့်ပြုချက်များမရှိပါက ကောင်းစွာမလုပ်ဆောင်ခြင်း ဖြစ်နိုင်သည်။ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>သုံးခွင့်ပြုနည်းကို လေ့လာရန်</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"အက်ပ်ကို သုံးခွင့် ငြင်းပယ်ထားသည်"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ဤခွင့်ပြုချက်သုံးခြင်းသည် သင်၏ ပုဂ္ဂိုလ်ရေးနှင့် ငွေကြေးဆိုင်ရာ အချက်အလက်များကို အန္တရာယ်ဖြစ်စေနိုင်သည်။<xliff:g id="ID_1"><br><br></xliff:g>အက်ပ်သည် ဤကန့်သတ်ထားသော ခွင့်ပြုချက်မရှိပါက ကောင်းစွာမလုပ်ဆောင်ခြင်း ဖြစ်နိုင်သည်။ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>သုံးခွင့်ပြုနည်းကို လေ့လာရန်</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ပိုမိုလေ့လာရန်"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"ခွင့်ပြုချက်တောင်းဆိုမှု ပိတ်ထားသည်"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ဤအက်ပ်သည် နောက်ထပ်ခွင့်ပြုချက်များကို တောင်းဆိုနေသော်လည်း တိုက်ရိုက်လွှင့်စက်ရှင်တွင် ခွင့်ပြုချက်များ ပေး၍မရပါ။ သင့်ဖုန်းတွင် ဦးစွာ ခွင့်ပြုချက်ပေးပါ။"</string> </resources> diff --git a/PermissionController/res/values-nb-v34/strings.xml b/PermissionController/res/values-nb-v34/strings.xml index a7bb456d5..d3fa18592 100644 --- a/PermissionController/res/values-nb-v34/strings.xml +++ b/PermissionController/res/values-nb-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Administrer apptilgang til helsedata"</string> <string name="location_settings" msgid="8863940440881290182">"Posisjonstilgang"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"For apper og tjenester. Hvis denne innstillingen er av, kan mikrofondata fremdeles deles når du ringer et nødnummer"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"For apper og tjenester"</string> </resources> diff --git a/PermissionController/res/values-nb-watch/strings.xml b/PermissionController/res/values-nb-watch/strings.xml index 3fc35f2c9..3a4f05c10 100644 --- a/PermissionController/res/values-nb-watch/strings.xml +++ b/PermissionController/res/values-nb-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Kan ikke endres"</string> <string name="generic_yes" msgid="2489207724988649846">"Ja"</string> <string name="generic_cancel" msgid="2631708607129269698">"Avbryt"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Hele tiden"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Når appen er i bruk"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Hele tiden"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Når appen er i bruk"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Hele tiden"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Når appen er i bruk"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Hele tiden"</string> </resources> diff --git a/PermissionController/res/values-nb/strings.xml b/PermissionController/res/values-nb/strings.xml index fc86eb79d..a8fbcb1d6 100644 --- a/PermissionController/res/values-nb/strings.xml +++ b/PermissionController/res/values-nb/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Alle tillatelser"</string> <string name="other_permissions" msgid="2901186127193849594">"Andre appfunksjoner"</string> <string name="permission_request_title" msgid="8790310151025020126">"Forespørsel om tillatelse"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Handlinger for å installere og avinstallere støttes ikke på Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Velg hva du vil gi <xliff:g id="APP_NAME">%1$s</xliff:g> tilgang til"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<xliff:g id="APP_NAME">%1$s</xliff:g> er oppdatert. Velg hva du vil gi denne appen tilgang til."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Avbryt"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Når nøyaktig posisjon er av, har apper tilgang til den omtrentlige posisjonen din"</string> <string name="app_permission_title" msgid="2090897901051370711">"Tillatelse: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Tilgang for denne appen: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g>-tilgang for denne appen på <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Se alle tillatelsene <xliff:g id="APP">%1$s</xliff:g> har"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Se alle apper med denne tillatelsen"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Vis bruk av assistentmikrofonen"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Fjern tillatelser hvis appen ikke brukes"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Fjern tillatelser og frigjør plass"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Sett appaktivitet på pause hvis ubrukt"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Administrer appen hvis den ikke brukes"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Fjern tillatelser, slett midlertidige filer, og stopp varsler"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Fjern tillatelser, slett midlertidige filer, stopp varsler, og arkiver appen"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"For å beskytte dataene dine fjernes tillatelser for denne appen hvis appen ikke brukes på noen måneder."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Hvis appen ikke brukes på noen måneder, fjernes disse tillatelsene for å beskytte dataene dine: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"For å beskytte dataene dine har tillatelser blitt fjernet fra apper du ikke har brukt på noen måneder."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Kan administrere alle filer"</string> <string name="ask_header" msgid="2633816846459944376">"Spør hver gang"</string> <string name="denied_header" msgid="903209608358177654">"Ikke tillatt"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> på <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Se flere apper som kan bruke alle filer"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dag}other{# dager}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# time}other{# timer}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notatapp"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apper du kan bruke til å ta notater på enheten"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notater"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Standard lommebokapp"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Lommebokapp"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"I lommebokapper kan du lagre kreditt- og stamkundekort, bilnøkler og andre ting for å få hjelp med ulike transaksjonstyper."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Vil du bruke <xliff:g id="APP_NAME">%1$s</xliff:g> som standard lommebokapp?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Ingen tillatelser er nødvendige"</string> <string name="request_role_current_default" msgid="738722892438247184">"Gjeldende standard"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ikke spør igjen"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Angi som standard"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Oppdateringer av datadeling"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Noen apper har endret hvordan de kan dele posisjonsdataene dine"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Innstillinger"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Åpnet <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Åpnet i går <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Åpnet <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Engangspassordet ditt er 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Begrenset innstilling"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Av sikkerhetshensyn er denne innstillingen utilgjengelig for øyeblikket."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Appens tilgang til <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> ble avvist"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Appen ba om tilgang til en sensitiv tillatelse som kan utsette den personlige og økonomiske informasjonen din for fare.<xliff:g id="ID_1"><br><br></xliff:g>Det kan hende at appen ikke fungerer skikkelig uten denne begrensede tillatelsen. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Finn ut hvordan du gir tilgang</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Appens tilgang til standard <xliff:g id="ROLE_NAME">%1$s</xliff:g>, ble avvist"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Appen ba om tilgang til sensitive tillatelser som kan utsette den personlige og økonomiske informasjonen din for fare.<xliff:g id="ID_1"><br><br></xliff:g>Det kan hende at appen ikke fungerer skikkelig uten disse begrensede tillatelsene. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Finn ut hvordan du gir tilgang</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Appens tilgang ble avvist"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Hvis du gir tilgang til denne tillatelsen, kan den personlige og økonomiske informasjonen din bli utsatt for fare.<xliff:g id="ID_1"><br><br></xliff:g>Det kan hende at appen ikke fungerer skikkelig uten denne begrensede tillatelsen. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Finn ut hvordan du gir tilgang</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Finn ut mer"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Forespørselen om tillatelse er skjult"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Denne appen ber om flere tillatelser, men du kan ikke gi tillatelser i en strømmeøkt. Gi tillatelsen på telefonen først."</string> </resources> diff --git a/PermissionController/res/values-ne-v34/strings.xml b/PermissionController/res/values-ne-v34/strings.xml index 421c5a8e0..89bb4279f 100644 --- a/PermissionController/res/values-ne-v34/strings.xml +++ b/PermissionController/res/values-ne-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"एपलाई स्वास्थ्यसम्बन्धी जानकारी प्रयोग गर्न दिने कि नदिने भन्ने कुरा व्यवस्थापन गर्नुहोस्"</string> <string name="location_settings" msgid="8863940440881290182">"लोकेसन एक्सेस"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"एप तथा सेवाहरूका हकमा। यो सेटिङ अफ गरिएको अवस्थामा तपाईंले आपत्कालीन नम्बरमा कल गर्नुभयो भने माइक्रोफोनसम्बन्धी जानकारी अझै पनि सेयर गरिन सक्छ"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"एप तथा सेवाहरूका हकमा"</string> </resources> diff --git a/PermissionController/res/values-ne-watch/strings.xml b/PermissionController/res/values-ne-watch/strings.xml index d5f1fc2ae..60374094c 100644 --- a/PermissionController/res/values-ne-watch/strings.xml +++ b/PermissionController/res/values-ne-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"बदल्न मिल्दैन"</string> <string name="generic_yes" msgid="2489207724988649846">"हुन्छ"</string> <string name="generic_cancel" msgid="2631708607129269698">"रद्द गर्नु…"</string> + <string name="permission_access_always" msgid="2107115233573823032">"सधैँ"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"एप प्रयोग गर्दा"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"सधैँ"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"एप प्रयोग गर्दा"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"सधैँ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"एप प्रयोग गर्दा"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"सधैँ"</string> </resources> diff --git a/PermissionController/res/values-ne/strings.xml b/PermissionController/res/values-ne/strings.xml index c934729fd..fba4231cc 100644 --- a/PermissionController/res/values-ne/strings.xml +++ b/PermissionController/res/values-ne/strings.xml @@ -32,9 +32,9 @@ <string name="grant_dialog_button_no_upgrade" msgid="8344732743633736625">"“एप प्रयोगमा भएको बेलामा” शीर्षक कायम राख्नुहोस्"</string> <string name="grant_dialog_button_no_upgrade_one_time" msgid="5125892775684968694">"“यस बेला मात्र” राख्नुहोस्"</string> <string name="grant_dialog_button_more_info" msgid="213350268561945193">"थप जानकारी"</string> - <string name="grant_dialog_button_allow_all" msgid="5939066403732409516">"सबै डेटा प्रयोग गर्ने अनुमति दिनुहोस्"</string> + <string name="grant_dialog_button_allow_all" msgid="5939066403732409516">"सबै अनुमति दिइयोस्"</string> <string name="grant_dialog_button_always_allow_all" msgid="1719900027660252167">"सधैँ सबै अनुमति दिइयोस्"</string> - <string name="grant_dialog_button_allow_limited_access" msgid="5713551784422137594">"सीमित एक्सेस दिनुहोस्"</string> + <string name="grant_dialog_button_allow_limited_access" msgid="5713551784422137594">"सीमित एक्सेस दिइयोस्"</string> <string name="grant_dialog_button_allow_selected_photos" msgid="5497042471576153842">"फोटो र भिडियोहरू चयन गर्नुहोस्"</string> <string name="grant_dialog_button_allow_more_selected_photos" msgid="5145657877588697709">"अझ धेरै फोटो चयन गर्नुहोस्"</string> <string name="grant_dialog_button_dont_select_more" msgid="6643552729129461268">"थप डेटा चयन नगर्नुहोस्"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"सबै अनुमति"</string> <string name="other_permissions" msgid="2901186127193849594">"एपका अन्य क्षमताहरू"</string> <string name="permission_request_title" msgid="8790310151025020126">"अनुमति दिन भनी गरिएको अनुरोध"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear मा स्थापना/स्थापना रद्द गर्ने कारबाहीहरू समर्थित छैनन्।"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई केमाथि पहुँच राख्न दिने हो छनौट गर्नुहोस्"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> अद्यावधिक गरिएको छ। यस एपलाई केमाथि पहुँच राख्न दिने हो छनौट गर्नुहोस्।"</string> <string name="review_button_cancel" msgid="2191147944056548886">"रद्द गर्नुहोस्"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"सटीक लोकेसन अफ हुँदा एपहरूलाई मेरो अनुमानित लोकेसन प्रयोग गर्न दिइयोस्"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>सम्बन्धी अनुमति"</string> <string name="app_permission_header" msgid="2951363137032603806">"यो एप <xliff:g id="PERM">%1$s</xliff:g> प्रयोग गर्ने अनुमति दिने वा नदिने"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"यो एपलाई <xliff:g id="DEVICE_NAME">%2$s</xliff:g> को <xliff:g id="PERM">%1$s</xliff:g> प्रयोग गर्ने अनुमति"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g> सँग भएका सबै अनुमति हेर्नुहोस्"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"यो अनुमति पाएका सबै एपहरू हेर्नुहोस्"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"सहायकको माइक्रोफोन प्रयोगसम्बन्धी डेटा देखाउनुहोस्"</string> <string name="unused_apps_category_title" msgid="2988455616845243901">"प्रयोग नगरिएको एपसम्बन्धी सेटिङ"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"यो एप प्रयोग नहुँदा यसलाई दिइएका अनुमतिहरू रद्द गरियोस्"</string> <string name="unused_apps_label" msgid="2595428768404901064">"अनुमतिहरू हटाई ठाउँ खाली गरियोस्"</string> - <string name="unused_apps_label_v2" msgid="7058776770056517980">"एप प्रयोग नगरिएको अवस्थामा उक्त एपमा बिताएको समय रेकर्ड नगरियोस्"</string> + <string name="unused_apps_label_v2" msgid="7058776770056517980">"एप प्रयोग नगरिएको अवस्थामा उक्त एपमा गरिएको गतिविधि रेकर्ड नगरियोस्"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"एप प्रयोग गरिएको छैन भने व्यवस्थापन गरियोस्"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"अनुमतिहरू रद्द गरियोस्, अस्थायी फाइलहरू मेटाइयोस् र एपसम्बन्धी सूचना नपठाइयोस्"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"अनुमति रद्द गरियोस्, अस्थायी फाइलहरू मेटाइयोस्, सूचना नपठाइयोस् र एप अभिलेखमा राखियोस्"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"तपाईंका डेटाको सुरक्षार्थ यो एप केही महिनासम्म प्रयोग नगरिएका खण्डमा यसलाई दिइएका अनुमति रद्द गरिने छन्।"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"तपाईंका डेटाको सुरक्षार्थ यो एप केही महिनासम्म प्रयोग नगरिएका खण्डमा निम्न अनुमति रद्द गरिने छन्: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"तपाईंका डेटाको सुरक्षार्थ तपाईंले केही महिनादेखि प्रयोग नगरेका एपलाई दिइएका अनुमति रद्द गरिएका छन्।"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"सबै फाइल व्यवस्थापन गर्ने अनुमति दिइएको"</string> <string name="ask_header" msgid="2633816846459944376">"प्रत्येक पटक सोधियोस्"</string> <string name="denied_header" msgid="903209608358177654">"अनुमति नदिइएका"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> को <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"सबै फाइल हेर्ने र प्रयोग गर्ने अनुमति भएका थप एपहरू हेर्नुहोस्"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{१ दिन}other{# दिन}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# घण्टा}other{# घण्टा}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"नोट एप"</string> <string name="role_notes_description" msgid="8496852798616883551">"तपाईंलाई आफ्नो डिभाइसमा नोट बनाउन दिने एपहरू"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"नोटहरू"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"डिफल्ट Wallet एप"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet एप"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"तपाईंलाई विभिन्न तरिकाले कारोबार गर्न सघाउन Wallet एपमा तपाईंका क्रेडिट कार्ड तथा लोयल्टी कार्ड, कार कीलगायतका कुराहरू पनि भण्डारण गर्न सकिन्छ।"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> लाई आफ्नो डिफल्ट Wallet एपका रूपमा सेट गर्ने हो?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"कुनै पनि अनुमति चाहिन्न"</string> <string name="request_role_current_default" msgid="738722892438247184">"हालको डिफल्ट एप"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"फेरि नसोध्नुहोस्"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"डिफल्ट सेट गर्नुहोस्"</string> @@ -429,7 +436,7 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"लिंकहरू खोल्दा"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"कार्यका लागि डिफल्ट"</string> <string name="default_app_none" msgid="9084592086808194457">"कुनै पनि होइन"</string> - <string name="default_app_system_default" msgid="6218386768175513760">"(डिफल्ट सिस्टम एप)"</string> + <string name="default_app_system_default" msgid="6218386768175513760">"(सिस्टम डिफल्ट)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"कुनै पनि एप छैन"</string> <string name="car_default_app_selected" msgid="5416420830430644174">"चयन गरिएको"</string> <string name="car_default_app_selected_with_info" msgid="1932204186080593500">"चयन गरिएको - <xliff:g id="ADDITIONAL_INFO">%1$s</xliff:g>"</string> @@ -445,14 +452,14 @@ <string name="incident_report_notification_text" msgid="3376480583513587923">"<xliff:g id="APP_NAME">%1$s</xliff:g> डिबग प्रक्रियासम्बन्धी जानकारी अपलोड गर्न चाहन्छ।"</string> <string name="incident_report_dialog_title" msgid="669104389325204095">"डिबग प्रक्रियासम्बन्धी डेटा सेयर गर्ने हो?"</string> <string name="incident_report_dialog_intro" msgid="5897733669850951832">"प्रणालीले कुनै समस्या फेला पारेको छ"</string> - <string name="incident_report_dialog_text" msgid="5675553296891757523">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ले <xliff:g id="DATE">%2$s</xliff:g> <xliff:g id="TIME">%3$s</xliff:g> मा यो यन्त्रबाट लिएको बगको रिपोर्ट अपलोड गर्ने अनुरोध गर्दै छ। बग रिपोर्टमा प्रयोगकर्ताका नाम, स्ठानसम्बन्धी डेटा, डिभाइसका पहिचानकर्ता र नेटवर्कसम्बन्धी जानकारी जस्ता तपाईंको डिभाइसको व्यक्तिगत जानकारी वा अनुप्रयोगले लग गरेको जानकारी समावेश छ। तपाईंलाई यो जानकारी दिँदा फरक पर्दैन जस्तो लाग्ने विश्वसनीय मान्छे वा एपसँग मात्र बग रिपोर्टहरू सेयर गर्नुहोस्। <xliff:g id="APP_NAME_1">%4$s</xliff:g> लाई बग रिपोर्ट अपलोड गर्न दिने हो?"</string> + <string name="incident_report_dialog_text" msgid="5675553296891757523">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> ले <xliff:g id="DATE">%2$s</xliff:g> <xliff:g id="TIME">%3$s</xliff:g> मा यो यन्त्रबाट लिएको बगको रिपोर्ट अपलोड गर्ने अनुरोध गर्दै छ। बग रिपोर्टमा प्रयोगकर्ताका नाम, स्ठानसम्बन्धी डेटा, डिभाइसका पहिचानकर्ता र नेटवर्कसम्बन्धी जानकारी जस्ता तपाईंको डिभाइसको व्यक्तिगत जानकारी वा एपले लग गरेको जानकारी समावेश छ। तपाईंलाई यो जानकारी दिँदा फरक पर्दैन जस्तो लाग्ने विश्वसनीय मान्छे वा एपसँग मात्र बग रिपोर्टहरू सेयर गर्नुहोस्। <xliff:g id="APP_NAME_1">%4$s</xliff:g> लाई बग रिपोर्ट अपलोड गर्न दिने हो?"</string> <string name="incident_report_error_dialog_text" msgid="4189647113387092272">"<xliff:g id="APP_NAME">%1$s</xliff:g> को बगसम्बन्धी रिपोर्ट प्रक्रियामा लैजाने क्रममा त्रुटि भयो। त्यस कारण विस्तृत डिबग प्रक्रियासम्बन्धी डेटा आदान प्रदान गर्ने कार्य अस्वीकार गरिएको छ। व्यवधानका लागि क्षमा गर्नुहोला।"</string> <string name="incident_report_dialog_allow_label" msgid="2970242967721155239">"अनुमति दिनुहोस्"</string> <string name="incident_report_dialog_deny_label" msgid="3535314290677579383">"अनुमति नदिनुहोस्"</string> <string name="adjust_user_sensitive_title" msgid="4196724451314280527">"उन्नत सेटिङहरू"</string> <string name="menu_adjust_user_sensitive" msgid="6497923610654425780">"उन्नत सेटिङहरू"</string> <string name="adjust_user_sensitive_globally_title" msgid="8649190949066029174">"प्रणालीका एपको प्रयोगसम्बन्धी जानकारी देखाउनुहोस्"</string> - <string name="adjust_user_sensitive_globally_summary" msgid="129467818433773912">"प्रणालीका अनुप्रयोगले गर्ने अनुमतिको प्रयोगसम्बन्धी जानकारी स्टाटस बार, ड्यासबोर्ड र अन्यत्र देखाउनुहोस्"</string> + <string name="adjust_user_sensitive_globally_summary" msgid="129467818433773912">"प्रणालीका एपले गर्ने अनुमतिको प्रयोगसम्बन्धी जानकारी स्टाटस बार, ड्यासबोर्ड र अन्यत्र देखाउनुहोस्"</string> <string name="adjust_user_sensitive_per_app_header" msgid="4543506440989005648">"निम्न एपको प्रयोगसम्बन्धी जानकारी हाइलाइट गर्नुहोस्"</string> <string name="assistant_record_audio_user_sensitive_title" msgid="5532123360322362378">"सहायक ट्रिगर भएको पत्ता लागेमा देखाउनुहोस्"</string> <string name="assistant_record_audio_user_sensitive_summary" msgid="6482937591816401619">"आवाज सहायक सक्रिय गर्न माइक्रोफोनको प्रयोग गरिँदा स्टाटस बारमा आइकन देखाउनुहोस्"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई कन्ट्याक्ट प्रयोग गर्न दिने हो?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई <b><xliff:g id="DEVICE">%2$s</xliff:g></b> मा भएका तपाईंका कन्ट्याक्टहरू एक्सेस गर्ने अनुमति दिने हो?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई यो डिभाइसको लोकेसन प्रयोग दिने हो?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई तपाईंको <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b> को लोकेसन एक्सेस गर्ने अनुमति दिने हो?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई तपाईंको <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> को लोकेसन एक्सेस गर्ने अनुमति दिने हो?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"तपाईंले एप प्रयोग गरिरहेका बेला मात्र उक्त एपले स्थानमाथि पहुँच राख्न सक्ने छ"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई यो डिभाइसको लोकेसन प्रयोग दिने हो?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई तपाईंको <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g> को लोकेसन एक्सेस गर्ने अनुमति दिने हो?"</string> @@ -565,7 +572,7 @@ <string name="privacy_controls_qs" msgid="5780144882040591169">"तपाईंका गोपनीयतासम्बन्धी सेटिङ"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"थप सेटिङ"</string> <string name="camera_toggle_label_qs" msgid="3880261453066157285">"क्यामेरा प्रयोग गर्ने अनुमति"</string> - <string name="microphone_toggle_label_qs" msgid="8132912469813396552">"माइक प्रयोग गर्ने अनुमति"</string> + <string name="microphone_toggle_label_qs" msgid="8132912469813396552">"माइक एक्सेस"</string> <string name="permissions_removed_qs" msgid="8957319130625294572">"अनुमति हटाइएको छ"</string> <string name="camera_usage_qs" msgid="4394233566086665994">"हालसालै गरिएको क्यामेराको प्रयोगसम्बन्धी जानकारी हेर्नुहोस्"</string> <string name="microphone_usage_qs" msgid="8527666682168170417">"हालसालै गरिएको माइकको प्रयोगसम्बन्धी जानकारी हेर्नुहोस्"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"जानकारी सेयर गर्नेसम्बन्धी अभ्यासका बारेमा अद्यावधिक जानकारी"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"केही एपहरूले तपाईंको लोकेसन डेटा सेयर गर्न सक्ने तरिका परिवर्तन गरेका छन्"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"सेटिङ"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> मा एक्सेस गरिएको"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"हिजो <xliff:g id="TIME_DATE">%1$s</xliff:g> मा एक्सेस गरिएको"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g> मा एक्सेस गरिएको"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"तपाईंको एक पटके पासवर्ड 132435 हो"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"प्रतिबन्ध लगाइएका सेटिङ"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"तपाईंको खाताको सुरक्षार्थ यो सेटिङ हाल उपलब्ध छैन।"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"एपले <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> प्रयोग गर्न मागेको अनुमति अस्वीकार गरिएको छ"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"यो एपले तपाईंको व्यक्तिगत तथा वित्तीय जानकारी जोखिममा पार्न सक्ने खालको संवेदनशील अनुमति मागेको छ।<xliff:g id="ID_1"><br><br></xliff:g>तपाईले उक्त प्रतिबन्धित अनुमति नदिएका खण्डमा यो एपले राम्रोसँग काम नगर्न सक्छ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>अनुमति दिने तरिका सिक्नुहोस्</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"यो एपले डिफल्ट <xliff:g id="ROLE_NAME">%1$s</xliff:g> का रूपमा काम गर्न मागेको अनुमति अस्वीकार गरिएको छ"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"यो एपले तपाईंका व्यक्तिगत तथा वित्तीय जानकारी जोखिममा पार्न सक्ने खालका संवेदनशील अनुमतिहरू मागेको छ।<xliff:g id="ID_1"><br><br></xliff:g>तपाईंले ती प्रतिबन्धित अनुमति नदिएका खण्डमा यो एपले राम्रोसँग काम नगर्न सक्छ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>अनुमति दिने तरिका सिक्नुहोस्</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"एपले मागेको अनुमति अस्वीकार गरिएको छ"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"तपाईंले यो अनुमति दिनुभयो भने तपाईंको व्यक्तिगत तथा वित्तीय जानकारी जोखिममा पर्न सक्छ।<xliff:g id="ID_1"><br><br></xliff:g>तपाईंले यो प्रतिबन्धित अनुमति नदिएका खण्डमा यो एपले राम्रोसँग काम नगर्न सक्छ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>अनुमति दिने तरिका सिक्नुहोस्</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"थप जान्नुहोस्"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ठिक छ"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"अनुमतिसम्बन्धी अनुरोध रद्द गरिएको छ"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"यो एपले अतिरिक्त अनुमति मागिरहेको छ तर स्ट्रिमिङ सत्रमा अनुमति दिन मिल्दैन। सर्वप्रथम आफ्नो फोनमा अनुमति दिनुहोस्।"</string> </resources> diff --git a/PermissionController/res/values-nl-v34/strings.xml b/PermissionController/res/values-nl-v34/strings.xml index b3265d254..8e0464cbb 100644 --- a/PermissionController/res/values-nl-v34/strings.xml +++ b/PermissionController/res/values-nl-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Beheer de toegang van apps tot je gezondheidsgegevens"</string> <string name="location_settings" msgid="8863940440881290182">"Locatietoegang"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Voor apps en services. Als deze instelling uitstaat, kunnen microfoongegevens nog altijd worden gedeeld als je een alarmnummer belt."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Voor apps en services"</string> </resources> diff --git a/PermissionController/res/values-nl-watch/strings.xml b/PermissionController/res/values-nl-watch/strings.xml index 454676644..4b70e1174 100644 --- a/PermissionController/res/values-nl-watch/strings.xml +++ b/PermissionController/res/values-nl-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Niet aanpasbaar"</string> <string name="generic_yes" msgid="2489207724988649846">"Ja"</string> <string name="generic_cancel" msgid="2631708607129269698">"Annuleren"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Altijd"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Bij gebruik van de app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Altijd"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Bij gebruik van de app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Altijd"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Bij gebruik van de app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Altijd"</string> </resources> diff --git a/PermissionController/res/values-nl/strings.xml b/PermissionController/res/values-nl/strings.xml index 22be451af..d372ceec2 100644 --- a/PermissionController/res/values-nl/strings.xml +++ b/PermissionController/res/values-nl/strings.xml @@ -51,7 +51,7 @@ <string name="permission_revoked_none" msgid="9213345075484381180">"geen rechten ingetrokken"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"Toestaan"</string> <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Altijd toestaan"</string> - <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Tijdens gebruik van de app"</string> + <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Tijdens gebruik van app"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"Wijzigen in exacte locatie"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"Geschatte locatie behouden"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"Alleen deze keer"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Alle rechten"</string> <string name="other_permissions" msgid="2901186127193849594">"Andere app-mogelijkheden"</string> <string name="permission_request_title" msgid="8790310151025020126">"Rechtenverzoek"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Acties voor installeren/verwijderen niet ondersteund op Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Kiezen waartoe <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang krijgt"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> is geüpdatet. Kies waartoe je deze app toegang wilt geven."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Annuleren"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Als de exacte locatie uitstaat, hebben apps toegang tot je geschatte locatie"</string> <string name="app_permission_title" msgid="2090897901051370711">"Rechten: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Toegang tot <xliff:g id="PERM">%1$s</xliff:g> voor deze app"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Toegang tot <xliff:g id="PERM">%1$s</xliff:g> voor deze app op <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Alle rechten van <xliff:g id="APP">%1$s</xliff:g> bekijken"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Alle apps met dit recht bekijken"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Gebruik van Assistent-microfoon tonen"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Rechten intrekken als app niet wordt gebruikt"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Rechten intrekken en ruimte vrijmaken"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"App-activiteit onderbreken indien niet gebruikt"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"App beheren indien ongebruikt"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Verwijder rechten en tijdelijke bestanden, en stop meldingen"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Verwijder rechten en tijdelijke bestanden, stop meldingen en archiveer de app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Om je gegevens te beschermen worden de rechten voor deze app verwijderd als de app een aantal maanden niet is gebruikt."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Om je gegevens te beschermen worden de volgende rechten ingetrokken als de app een paar maanden niet is gebruikt: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Om je gegevens te beschermen zijn de rechten verwijderd van apps die al een paar maanden niet zijn gebruikt."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Alle bestanden beheren"</string> <string name="ask_header" msgid="2633816846459944376">"Altijd vragen"</string> <string name="denied_header" msgid="903209608358177654">"Niet toegestaan"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> in <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Bekijk meer apps die toegang tot alle bestanden hebben."</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dag}other{# dagen}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# uur}other{# uur}}"</string> @@ -371,7 +373,7 @@ <string name="role_sms_search_keywords" msgid="8022048144395047352">"tekst bericht, tekstbericht, sms, sms\'en, berichten, verzenden, sturen"</string> <string name="role_emergency_label" msgid="7028825857206842366">"Standaardapp voor noodgevallen"</string> <string name="role_emergency_short_label" msgid="2388431453335350348">"Nood-app"</string> - <string name="role_emergency_description" msgid="5051840234887686630">"Apps waarmee je je medische gegevens kunt vastleggen en toegankelijk kunt maken voor hulpverleners; apps waarmee je waarschuwingen ontvangt voor gevaarlijk weer of rampen; apps waarmee je mensen kunt laten weten dat je hulp nodig hebt"</string> + <string name="role_emergency_description" msgid="5051840234887686630">"Apps waarmee je je medische info kunt vastleggen en toegankelijk kunt maken voor hulpverleners; apps waarmee je waarschuwingen krijgt voor gevaarlijk weer of rampen; apps waarmee je mensen kunt laten weten dat je hulp nodig hebt"</string> <string name="role_emergency_request_title" msgid="8469579020654348567">"Wil je <xliff:g id="APP_NAME">%1$s</xliff:g> instellen als je standaard-app voor noodgevallen?"</string> <string name="role_emergency_request_description" msgid="131645948770262850">"Geen rechten nodig"</string> <string name="role_emergency_search_keywords" msgid="1920007722599213358">"bij noodgevallen"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notitie-app"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps waarmee je notities op je apparaat kunt maken"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notities"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Standaard digitale portemonnee-app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Digitale portemonnee-app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Digitale portemonnee-apps kunnen je creditcards en klantenkaarten, autosleutels en andere zaken opslaan om je te helpen bij verschillende vormen van transacties."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> instellen als je standaard digitale portemonnee-app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Geen rechten nodig"</string> <string name="request_role_current_default" msgid="738722892438247184">"Huidige standaard-app"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Niet meer vragen"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Standaard instellen"</string> @@ -458,12 +465,12 @@ <string name="assistant_record_audio_user_sensitive_summary" msgid="6482937591816401619">"Icoon op statusbalk tonen als microfoon wordt gebruikt om de Spraakassistent te activeren"</string> <string name="permgrouprequest_storage_isolated" msgid="4892154224026852295">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot foto\'s en media op je apparaat?"</string> <string name="permgrouprequest_device_aware_storage_isolated" msgid="5934218468708513375">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot foto\'s en media op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_contacts" msgid="8391550064551053695">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot je contacten?"</string> + <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang heeft tot je contacten?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot de contacten op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_location" msgid="6990232580121067883">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot de locatie van dit apparaat?"</string> + <string name="permgrouprequest_location" msgid="6990232580121067883">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang heeft tot de locatie van dit apparaat?"</string> <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot de locatie van je <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"De app heeft alleen toegang tot de locatie wanneer je de app gebruikt"</string> - <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot de locatie van dit apparaat?"</string> + <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang heeft tot de locatie van dit apparaat?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot de locatie van je <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>?"</string> <string name="permgroupbackgroundrequestdetail_location" msgid="8021219324989662957">"Deze app wil mogelijk altijd toegang tot je locatie, ook als je de app niet gebruikt. "<annotation id="link">"Je kunt dit toestaan via de instellingen."</annotation></string> <string name="permgroupupgraderequest_location" msgid="8328408946822691636">"Toegang tot locatie wijzigen voor <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>?"</string> @@ -488,14 +495,14 @@ <string name="permgrouprequest_storage_pre_q" msgid="168130651144569428">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot <b>foto\'s, video\'s, muziek, audio en andere bestanden</b> op dit apparaat?"</string> <string name="permgrouprequest_read_media_aural" msgid="2593365397347577812">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot muziek en audio op dit apparaat?"</string> <string name="permgrouprequest_device_aware_read_media_aural" msgid="3331524384339036668">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot muziek en audio op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot foto\'s en video\'s op dit apparaat?"</string> + <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang heeft tot foto\'s en video\'s op dit apparaat?"</string> <string name="permgrouprequest_device_aware_read_media_visual" msgid="5492319750632751551">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot foto\'s en video\'s op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_more_photos" msgid="128933814654231321">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot meer foto\'s en video\'s op dit apparaat?"</string> <string name="permgrouprequest_device_aware_more_photos" msgid="8946782319103584021">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot meer foto\'s en video\'s op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_microphone" msgid="2825208549114811299">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om audio op te nemen?"</string> + <string name="permgrouprequest_microphone" msgid="2825208549114811299">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> audio opneemt?"</string> <string name="permgrouprequest_device_aware_microphone" msgid="1266843551173029370">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om audio op te nemen op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_microphone" msgid="8510456971528228861">"Deze app kan alleen audio opnemen als je de app gebruikt"</string> - <string name="permgroupbackgroundrequest_microphone" msgid="8874462606796368183">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om audio op te nemen?"</string> + <string name="permgroupbackgroundrequest_microphone" msgid="8874462606796368183">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> audio opneemt?"</string> <string name="permgroupbackgroundrequest_device_aware_microphone" msgid="4990337225146130185">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om audio op te nemen op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgroupbackgroundrequestdetail_microphone" msgid="553702902263681838">"Deze app wil mogelijk altijd audio opnemen, ook als je de app niet gebruikt. "<annotation id="link">"Toestaan in instellingen."</annotation></string> <string name="permgroupupgraderequest_microphone" msgid="1362781696161233341">"Toegang tot microfoon wijzigen voor <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>?"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"Deze app wil altijd audio opnemen, ook als je de app niet gebruikt. "<annotation id="link">"Toestaan in instellingen."</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot je fysieke activiteit?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot je fysieke activiteit op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om foto\'s te maken en video\'s op te nemen?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> foto\'s maakt en video\'s opneemt?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om foto\'s te maken en video\'s op te nemen op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"Deze app kan alleen foto\'s maken en video\'s opnemen als je de app gebruikt"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om foto\'s te maken en video\'s op te nemen?"</string> @@ -512,9 +519,9 @@ <string name="permgroupupgraderequest_camera" msgid="640758449200241582">"Toegang tot camera wijzigen voor <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>?"</string> <string name="permgroupupgraderequest_device_aware_camera" msgid="4198765626608612156">"Toegang tot camera wijzigen voor <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgroupupgraderequestdetail_camera" msgid="6642747548010962597">"Deze app wil altijd foto\'s maken en video\'s opnemen, ook als je de app niet gebruikt. "<annotation id="link">"Toestaan in Instellingen."</annotation></string> - <string name="permgrouprequest_calllog" msgid="2065327180175371397">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot je gesprekslijsten?"</string> + <string name="permgrouprequest_calllog" msgid="2065327180175371397">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang heeft tot je gesprekslijsten?"</string> <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot de gesprekslijsten op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_phone" msgid="1829234136997316752">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om telefoongesprekken te starten en te beheren?"</string> + <string name="permgrouprequest_phone" msgid="1829234136997316752">"Toestaan dat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> telefoongesprekken start en beheert?"</string> <string name="permgrouprequest_device_aware_phone" msgid="4389610977195521813">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toestaan om telefoongesprekken te starten en te beheren op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_sensors" msgid="4397358316850652235">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot sensorgegevens over je vitale functies?"</string> <string name="permgrouprequest_device_aware_sensors" msgid="1900598688488188225">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang geven tot sensorgegevens over je vitale functies op je <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> @@ -610,7 +617,7 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"Microfoontoegang"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Voor apps en services"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Voor apps en services. Als deze instelling uitstaat, kunnen microfoongegevens nog altijd worden gedeeld als je een alarmnummer belt."</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"Bekijk apps en services die toegang hebben tot die locatie"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"Bekijk apps en services die toegang hebben tot de locatie"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Toegang tot klembord tonen"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Toon een bericht als apps toegang hebben tot tekst, afbeeldingen of andere content die je hebt gekopieerd"</string> <string name="show_password_title" msgid="2877269286984684659">"Wachtwoorden tonen"</string> @@ -637,7 +644,7 @@ <string name="app_location_permission_rationale_title" msgid="925420340572401350">"Locatiegegevens kunnen worden gedeeld"</string> <string name="app_location_permission_rationale_subtitle" msgid="6986985722752868692">"Deze app geeft aan dat je locatiegegevens met derden kunnen worden gedeeld"</string> <string name="data_sharing_updates_title" msgid="7996933386875213859">"Updates voor het delen van locatiegegevens"</string> - <string name="data_sharing_updates_summary" msgid="764113985772233889">"Check apps die de manier hebben veranderd waarop je locatiegegevens worden gedeeld"</string> + <string name="data_sharing_updates_summary" msgid="764113985772233889">"Ga na welke apps de manier hebben veranderd waarop je locatiegegevens worden gedeeld"</string> <string name="data_sharing_updates_subtitle" msgid="6311537708950632329">"Deze apps hebben de manier veranderd waarop ze je locatiegegevens kunnen delen. Misschien deelden ze de gegevens eerder niet, of kunnen ze deze nu delen voor reclame- en marketingdoeleinden."</string> <string name="data_sharing_updates_footer_message" msgid="1582711655172892107">"De ontwikkelaars van deze apps hebben informatie gegeven aan een appstore over hun procedures voor gegevens delen. Ze kunnen deze informatie in de loop van de tijd updaten.\n\nProcedures voor gegevens delen kunnen verschillen op basis van je app-versie, gebruik, regio en leeftijd."</string> <string name="learn_about_data_sharing" msgid="4200480587079488045">"Meer informatie over gegevens delen"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Updates voor gegevens delen"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Sommige apps kunnen je locatiegegevens nu op een andere manier delen"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Instellingen"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Geopend: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Geopend: gisteren om <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Geopend: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> om <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Je eenmalige wachtwoord is 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Beperkte instelling"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Ter beveiliging is deze instelling op dit moment niet beschikbaar."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"App heeft geen toegang gekregen tot <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"De app heeft toegang gevraagd tot een gevoelig recht, waardoor je persoonlijke en financiële informatie risico kunnen lopen.<xliff:g id="ID_1"><br><br></xliff:g>Het is mogelijk dat de app niet goed werkt zonder dit beperkte recht. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Meer informatie over hoe je toegang geeft</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"App heeft geen toegang gekregen om de standaard <xliff:g id="ROLE_NAME">%1$s</xliff:g> te worden"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"De app heeft toegang gevraagd tot gevoelige rechten, waardoor je persoonlijke en financiële informatie risico kunnen lopen.<xliff:g id="ID_1"><br><br></xliff:g>Het is mogelijk dat de app niet goed werkt zonder deze beperkte rechten. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Meer informatie over hoe je toegang geeft</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"App heeft geen toegang gekregen"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Als je toegang geeft tot dit recht, kunnen je persoonlijke en financiële informatie risico lopen.<xliff:g id="ID_1"><br><br></xliff:g>Het is mogelijk dat de app niet goed werkt zonder dit beperkte recht. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Meer informatie over hoe je toegang geeft</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Meer informatie"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Verzoek om rechten onderdrukt"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Deze app vraagt om extra rechten, maar je kunt geen rechten verlenen tijdens een streamingsessie. Verleen het recht eerst op je telefoon."</string> </resources> diff --git a/PermissionController/res/values-or-v34/strings.xml b/PermissionController/res/values-or-v34/strings.xml index 2994a3f25..8e9b52f97 100644 --- a/PermissionController/res/values-or-v34/strings.xml +++ b/PermissionController/res/values-or-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ସ୍ୱାସ୍ଥ୍ୟ ଡାଟା ପାଇଁ ଆପର ଆକ୍ସେସକୁ ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="location_settings" msgid="8863940440881290182">"ଲୋକେସନ ଆକ୍ସେସ"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ଆପ୍ସ ଏବଂ ସେବାଗୁଡ଼ିକ ପାଇଁ। ଯଦି ଏହି ସେଟିଂ ବନ୍ଦ ଥାଏ, ତେବେ ଆପଣ ଏକ ଜରୁରୀକାଳୀନ ନମ୍ବରକୁ କଲ କରିବା ସମୟରେ ମାଇକ୍ରୋଫୋନ ଡାଟା ଏବେ ବି ସେୟାର କରାଯାଇପାରେ"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ଆପ୍ସ ଏବଂ ସେବାଗୁଡ଼ିକ ପାଇଁ"</string> </resources> diff --git a/PermissionController/res/values-or-watch/strings.xml b/PermissionController/res/values-or-watch/strings.xml index ef9515f25..579128b3f 100644 --- a/PermissionController/res/values-or-watch/strings.xml +++ b/PermissionController/res/values-or-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ଏହା ବଦଳାଯାଇପାରିବ ନାହିଁ"</string> <string name="generic_yes" msgid="2489207724988649846">"ହଁ"</string> <string name="generic_cancel" msgid="2631708607129269698">"ବାତିଲ କରନ୍ତୁ"</string> + <string name="permission_access_always" msgid="2107115233573823032">"ସର୍ବଦା"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ଆପ ବ୍ୟବହାର କରିବା ସମୟରେ"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"ସର୍ବଦା"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ଆପ ବ୍ୟବହାର କରିବା ସମୟରେ"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"ସର୍ବଦା"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ଆପ ବ୍ୟବହାର କରିବା ସମୟରେ"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"ସର୍ବଦା"</string> </resources> diff --git a/PermissionController/res/values-or/strings.xml b/PermissionController/res/values-or/strings.xml index beb7572ba..bcdb1c8d9 100644 --- a/PermissionController/res/values-or/strings.xml +++ b/PermissionController/res/values-or/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ସମସ୍ତ ଅନୁମତିଗୁଡ଼ିକ"</string> <string name="other_permissions" msgid="2901186127193849594">"ଅନ୍ୟାନ୍ୟ ଆପ୍ ଦକ୍ଷତା"</string> <string name="permission_request_title" msgid="8790310151025020126">"ଅନୁମତି ଅନୁରୋଧ"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android ୱିୟର୍"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"ୱିୟର୍ରେ ଇନଷ୍ଟଲ୍/ଅନଇନଷ୍ଟଲ୍ କାର୍ଯ୍ୟଗୁଡ଼ିକ ସମର୍ଥନ କରେନାହିଁ।"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ଆକ୍ସେସ୍ କରିବା ପାଇଁ କେଉଁସବୁ ଅନୁମତି ଦିଆଯିବ, ତାହା ବାଛନ୍ତୁ"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ଅପଡେଟ୍ କରାଯାଇଛି। ଏହି ଆପ୍ କେଉଁସବୁ ଆକ୍ସେସ୍ କରିପାରିବ, ତାହା ବାଛନ୍ତୁ।"</string> <string name="review_button_cancel" msgid="2191147944056548886">"ବାତିଲ କରନ୍ତୁ"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"ଯେତେବେଳେ ସଠିକ୍ ଲୋକେସନ୍ ବନ୍ଦ ଥାଏ, ସେତେବେଳେ ଆପଗୁଡ଼ିକ ଆପଣଙ୍କ ଆନୁମାନିକ ଲୋକେସନକୁ ଆକ୍ସେସ୍ କରିପାରିବ"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> ଅନୁମତି"</string> <string name="app_permission_header" msgid="2951363137032603806">"ଏହି ଆପ ପାଇଁ <xliff:g id="PERM">%1$s</xliff:g>ର ଆକ୍ସେସ"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>ରେ ଏହି ଆପ ପାଇଁ <xliff:g id="PERM">%1$s</xliff:g> ଆକ୍ସେସ ଅଛି"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"ସମସ୍ତ <xliff:g id="APP">%1$s</xliff:g> ଅନୁମତି ଦେଖନ୍ତୁ"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ଏହି ଅନୁମତି ଥିବା ସମସ୍ତ ଆପ୍ସ ଦେଖନ୍ତୁ"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistant ମାଇକ୍ରୋଫୋନ୍ ବ୍ୟବହାର ଦେଖାନ୍ତୁ"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ଯଦି ଆପ୍ ବ୍ୟବହାର କରାଯାଇନାହିଁ, ତେବେ ଅନୁମତିଗୁଡ଼ିକୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string> <string name="unused_apps_label" msgid="2595428768404901064">"ଅନୁମତିଗୁଡ଼ିକୁ କାଢ଼ି ସ୍ପେସ୍ ଖାଲି କରନ୍ତୁ"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"ବ୍ୟବହାର ହେଉନଥିଲେ ଆପ କାର୍ଯ୍ୟକଳାପ ବିରତ କରନ୍ତୁ"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ଆପକୁ ବ୍ୟବହାର କରାଯାଉନଥିଲେ ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ଅନୁମତିଗୁଡ଼ିକୁ କାଢ଼ି ଦିଅନ୍ତୁ, ଅସ୍ଥାୟୀ ଫାଇଲଗୁଡ଼ିକୁ ଡିଲିଟ କରନ୍ତୁ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ଅନୁମତିଗୁଡ଼ିକୁ କାଢ଼ି ଦିଅନ୍ତୁ, ଅସ୍ଥାୟୀ ଫାଇଲଗୁଡ଼ିକୁ ଡିଲିଟ କରନ୍ତୁ, ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ ଏବଂ ଆପକୁ ଆର୍କାଇଭ କରନ୍ତୁ"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"ଯଦି ଏହି ଆପକୁ କିଛି ମାସ ପାଇଁ ବ୍ୟବହାର କରାଯାଇନାହିଁ, ତେବେ ଆପଣଙ୍କ ଡାଟାର ସୁରକ୍ଷା ନିମନ୍ତେ ଏହାର ଅନୁମତିଗୁଡ଼ିକୁ କାଢ଼ି ଦିଆଯିବ।"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"ଯଦି ଏହି ଆପକୁ କିଛି ମାସ ପାଇଁ ବ୍ୟବହାର କରାଯାଇନାହିଁ ତେବେ ଆପଣଙ୍କ ଡାଟାର ସୁରକ୍ଷା ନିମନ୍ତେ, ନିମ୍ନୋକ୍ତ ଅନୁମତିଗୁଡ଼ିକୁ କାଢ଼ି ଦିଆଯିବ: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"ଆପଣଙ୍କ ଡାଟାର ସୁରକ୍ଷା ପାଇଁ, ଆପଣ କିଛି ମାସ ହେଲା ବ୍ୟବହାର କରିନଥିବା ଆପଗୁଡ଼ିକରୁ ଅନୁମତିଗୁଡ଼ିକୁ କାଢ଼ି ଦିଆଯାଇଛି।"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ସମସ୍ତ ଫାଇଲ୍ ପରିଚାଳନା କରିବାକୁ ଅନୁମତି ଦିଆଯାଇଛି"</string> <string name="ask_header" msgid="2633816846459944376">"ପ୍ରତ୍ୟେକ ଥର ପଚାରନ୍ତୁ"</string> <string name="denied_header" msgid="903209608358177654">"ଅନୁମତି ନାହିଁ"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>ର <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ସମସ୍ତ ଫାଇଲକୁ ଆକ୍ସେସ କରିପାରୁଥିବା ଅଧିକ ଆପ୍ସ ଦେଖନ୍ତୁ"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ଦିନ}other{# ଦିନ}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ଘଣ୍ଟା}other{# ଘଣ୍ଟା}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"ନୋଟ୍ସ ଆପ"</string> <string name="role_notes_description" msgid="8496852798616883551">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପଣଙ୍କୁ ନୋଟ ନେବା ପାଇଁ ଅନୁମତି ଦେଉଥିବା ଆପ୍ସ"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ନୋଟ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ଡିଫଲ୍ଟ ୱାଲେଟ ଆପ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"ୱାଲେଟ ଆପ"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"ବିଭିନ୍ନ ପ୍ରକାରର ଟ୍ରାଞ୍ଜେକସନରେ ସାହାଯ୍ୟ କରିବାକୁ ୱାଲେଟ ଆପ୍ସ ଆପଣଙ୍କ କ୍ରେଡିଟ ଓ ଲୟାଲ୍ଟି କାର୍ଡ, କାର କୀ ଏବଂ ଅନ୍ୟ ଜିନିଷଗୁଡ଼ିକୁ ଷ୍ଟୋର କରିପାରିବ।"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g>କୁ ଆପଣଙ୍କ ଡିଫଲ୍ଟ ୱାଲେଟ ଆପ ଭାବେ ସେଟ କରିବେ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"କୌଣସି ଅନୁମତି ଆବଶ୍ୟକ ନାହିଁ"</string> <string name="request_role_current_default" msgid="738722892438247184">"ସମ୍ପ୍ରତ୍ତି ଡିଫଲ୍ଟ"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ଆଉ ପଚାରନ୍ତୁ ନାହିଁ"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ଡିଫଲ୍ଟ ଭାବେ ସେଟ୍ କରନ୍ତୁ"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ଡାଟା ସେୟାରିଂ ଅପଡେଟଗୁଡ଼ିକ"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"କିଛି ଆପ୍ସ ଆପଣଙ୍କ ଲୋକେସନ ଡାଟା ସେୟାର କରିବା ଉପାୟକୁ ପରିବର୍ତ୍ତନ କରିଛି"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ସେଟିଂସ"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇଛି"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"ଗତକାଲି <xliff:g id="TIME_DATE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇଛି"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇଛି"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ଆପଣଙ୍କ ଗୋଟିଏ ଥରର ପାସୱାର୍ଡ ହେଉଛି 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"ପ୍ରତିବନ୍ଧିତ ସେଟିଂ"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"ଆପଣଙ୍କ ସୁରକ୍ଷା ପାଇଁ ଏହି ସେଟିଂ ବର୍ତ୍ତମାନ ଅନୁପଲବ୍ଧ ଅଟେ।"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>କୁ ଆପର ଆକ୍ସେସକୁ ଅଗ୍ରାହ୍ୟ କରାଯାଇଛି"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଏବଂ ଆର୍ଥିକ ସୂଚନାକୁ ବିପଦରେ ପକାଇପାରୁଥିବା ଏକ ସମ୍ବେଦନଶୀଳ ଅନୁମତିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପଟି ଅନୁରୋଧ କରିଛି।<xliff:g id="ID_1"><br><br></xliff:g>ଏହା ସମ୍ଭବ ଯେ ଏହି ପ୍ରତିବନ୍ଧିତ ଅନୁମତି ବିନା ଆପ ସଠିକ ଭାବେ କାର୍ଯ୍ୟ କରିବ ନାହିଁ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ଆକ୍ସେସକୁ କିପରି ଅନୁମତି ଦେବେ ତାହା ଜାଣନ୍ତୁ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ଡିଫଲ୍ଟ <xliff:g id="ROLE_NAME">%1$s</xliff:g> ହେବା ପାଇଁ ଆପର ଆକ୍ସେସକୁ ଅଗ୍ରାହ୍ୟ କରାଯାଇଛି"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଏବଂ ଆର୍ଥିକ ସୂଚନାକୁ ବିପଦରେ ପକାଇପାରୁଥିବା ସମ୍ବେଦନଶୀଳ ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପଟି ଅନୁରୋଧ କରିଛି।<xliff:g id="ID_1"><br><br></xliff:g>ଏହା ସମ୍ଭବ ଯେ ଏହି ପ୍ରତିବନ୍ଧିତ ଅନୁମତିଗୁଡ଼ିକ ବିନା ଆପ ସଠିକ ଭାବେ କାର୍ଯ୍ୟ କରିବ ନାହିଁ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ଆକ୍ସେସକୁ କିପରି ଅନୁମତି ଦେବେ ତାହା ଜାଣନ୍ତୁ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ଆପର ଆକ୍ସେସକୁ ଅଗ୍ରାହ୍ୟ କରାଯାଇଛି"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ଏହି ଅନୁମତିକୁ ଆକ୍ସେସ ଆପଣଙ୍କ ବ୍ୟକ୍ତିଗତ ଏବଂ ଆର୍ଥିକ ସୂଚନାକୁ ବିପଦରେ ପକାଇପାରେ।<xliff:g id="ID_1"><br><br></xliff:g>ଏହା ସମ୍ଭବ ଯେ ଏହି ପ୍ରତିବନ୍ଧିତ ଅନୁମତି ବିନା ଆପ ସଠିକ ଭାବେ କାର୍ଯ୍ୟ କରିବ ନାହିଁ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ଆକ୍ସେସକୁ କିପରି ଅନୁମତି ଦେବେ ତାହା ଜାଣନ୍ତୁ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ଅଧିକ ଜାଣନ୍ତୁ"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ଠିକ ଅଛି"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"ଅନୁମତି ଅନୁରୋଧକୁ ବନ୍ଦ କରାଯାଇଛି"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ଏହି ଆପ ଅତିରିକ୍ତ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି, ଏକ ଷ୍ଟ୍ରିମିଂ ସେସନରେ ଅନୁମତି ଦିଆଯାଇପାରିବ ନାହିଁ। ପ୍ରଥମେ ଆପଣଙ୍କ ଫୋନରେ ଅନୁମତି ଦିଅନ୍ତୁ।"</string> </resources> diff --git a/PermissionController/res/values-pa-v33/strings.xml b/PermissionController/res/values-pa-v33/strings.xml index 03e18ae50..0aa143302 100644 --- a/PermissionController/res/values-pa-v33/strings.xml +++ b/PermissionController/res/values-pa-v33/strings.xml @@ -28,9 +28,9 @@ <string name="safety_center_entry_group_item_content_description" msgid="7348298582877249787">"ਸੂਚੀ ਆਈਟਮ। <xliff:g id="ENTRY_ITEM_TITLE">%1$s</xliff:g>. <xliff:g id="ENTRY_ITEM_SUMMARY">%2$s</xliff:g>"</string> <string name="safety_center_entry_content_description" msgid="3639565652938224321">"<xliff:g id="ENTRY_ITEM_TITLE">%1$s</xliff:g>. <xliff:g id="ENTRY_ITEM_SUMMARY">%2$s</xliff:g>"</string> <string name="safety_center_more_issues_card_title" msgid="7425844746197493312">"ਹੋਰ ਅਲਰਟ"</string> - <string name="safety_center_dismissed_issues_card_title" msgid="2340129842725145733">"ਖਾਰਜ ਕੀਤੀਆਂ ਗਈਆਂ ਸੁਚੇਤਨਾਵਾਂ"</string> - <string name="safety_center_more_issues_card_expand_action" msgid="7109451851052272946">"{count,plural, =1{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ ਇੱਕ ਹੋਰ ਸੁਚੇਤਨਾ ਦੇਖੋ}one{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ # ਹੋਰ ਸੁਚੇਤਨਾ ਦੇਖੋ}other{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ # ਹੋਰ ਸੁਚੇਤਨਾਵਾਂ ਦੇਖੋ}}"</string> - <string name="safety_center_issue_card_prefix_content_description" msgid="1447445289637043544">"ਸੁਚੇਤਨਾ। <xliff:g id="ISSUE_CARD_TITLE">%1$s</xliff:g>"</string> + <string name="safety_center_dismissed_issues_card_title" msgid="2340129842725145733">"ਖਾਰਜ ਕੀਤੇ ਅਲਰਟ"</string> + <string name="safety_center_more_issues_card_expand_action" msgid="7109451851052272946">"{count,plural, =1{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ ਇੱਕ ਹੋਰ ਅਲਰਟ ਦੇਖੋ}one{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ # ਹੋਰ ਅਲਰਟ ਦੇਖੋ}other{ਵਿਸਤਾਰ ਕਰੋ ਅਤੇ # ਹੋਰ ਅਲਰਟ ਦੇਖੋ}}"</string> + <string name="safety_center_issue_card_prefix_content_description" msgid="1447445289637043544">"ਅਲਰਟ। <xliff:g id="ISSUE_CARD_TITLE">%1$s</xliff:g>"</string> <string name="safety_center_resolved_issue_fallback" msgid="8548932070610766651">"ਕਾਰਵਾਈ ਪੂਰੀ ਹੋਈ"</string> <string name="safety_center_qs_status_summary" msgid="5193925895830451177">"ਉਨ੍ਹਾਂ ਸੈਟਿੰਗਾਂ ਦੀ ਜਾਂਚ ਕਰੋ ਜੋ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀਆਂ ਹਨ"</string> <string name="safety_center_qs_page_landing" msgid="1717368301679228128">"ਸੁਰੱਖਿਆ ਅਤੇ ਪਰਦੇਦਾਰੀ ਸੰਬੰਧੀ ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ"</string> diff --git a/PermissionController/res/values-pa-v34/strings.xml b/PermissionController/res/values-pa-v34/strings.xml index c0b70fb57..ff5c1c7d6 100644 --- a/PermissionController/res/values-pa-v34/strings.xml +++ b/PermissionController/res/values-pa-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ਸਿਹਤ ਸੰਬੰਧੀ ਡਾਟੇ ਤੱਕ ਐਪ ਦੀ ਪਹੁੰਚ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="location_settings" msgid="8863940440881290182">"ਟਿਕਾਣਾ ਪਹੁੰਚ"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ। ਇਸ ਸੈਟਿੰਗ ਦੇ ਬੰਦ ਹੋਣ \'ਤੇ, ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਐਮਰਜੈਂਸੀ ਨੰਬਰ \'ਤੇ ਕਾਲ ਕਰਦੇ ਹੋ ਤਾਂ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਡਾਟੇ ਨੂੰ ਫਿਰ ਵੀ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ਐਪਾਂ ਅਤੇ ਸੇਵਾਵਾਂ ਲਈ"</string> </resources> diff --git a/PermissionController/res/values-pa-watch/strings.xml b/PermissionController/res/values-pa-watch/strings.xml index 8a46aef6f..3bac90bee 100644 --- a/PermissionController/res/values-pa-watch/strings.xml +++ b/PermissionController/res/values-pa-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string> <string name="generic_yes" msgid="2489207724988649846">"ਹਾਂ"</string> <string name="generic_cancel" msgid="2631708607129269698">"ਰੱਦ ਕਰੋ"</string> + <string name="permission_access_always" msgid="2107115233573823032">"ਹਰ ਸਮੇਂ"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ਐਪ ਦੀ ਵਰਤੋਂ ਦੌਰਾਨ"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"ਹਰ ਸਮੇਂ"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ਐਪ ਦੀ ਵਰਤੋਂ ਦੌਰਾਨ"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"ਹਰ ਸਮੇਂ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ਐਪ ਦੀ ਵਰਤੋਂ ਦੌਰਾਨ"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"ਹਰ ਸਮੇਂ"</string> </resources> diff --git a/PermissionController/res/values-pa/strings.xml b/PermissionController/res/values-pa/strings.xml index b69db6992..85adb713b 100644 --- a/PermissionController/res/values-pa/strings.xml +++ b/PermissionController/res/values-pa/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"ਸਾਰੀਆਂ ਇਜਾਜ਼ਤਾਂ"</string> <string name="other_permissions" msgid="2901186127193849594">"ਐਪ ਦੀਆਂ ਹੋਰ ਸਮਰੱਥਤਾਵਾਂ"</string> <string name="permission_request_title" msgid="8790310151025020126">"ਇਜਾਜ਼ਤ ਬੇਨਤੀ"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear \'ਤੇ ਸਥਾਪਤ/ਅਣਸਥਾਪਤ ਕਰਨ ਦੀਆਂ ਕਾਰਵਾਈਆਂ ਸਮਰਥਿਤ ਨਹੀਂ ਹਨ।"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"ਇਹ ਚੁਣੋ ਕਿ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਕਿਸ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ। ਇਹ ਚੁਣੋ ਕਿ ਇਸ ਐਪ ਨੂੰ ਕਿਸ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ।"</string> <string name="review_button_cancel" msgid="2191147944056548886">"ਰੱਦ ਕਰੋ"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"ਜਦੋਂ ਸਹੀ ਟਿਕਾਣੇ ਦੀ ਜਾਣਕਾਰੀ ਬੰਦ ਹੋਵੇ, ਤਾਂ ਐਪਾਂ ਤੁਹਾਡੀ ਅੰਦਾਜ਼ਨ ਟਿਕਾਣੇ ਦੀ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀਆਂ ਹਨ"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> ਸੰਬੰਧੀ ਇਜਾਜ਼ਤ"</string> <string name="app_permission_header" msgid="2951363137032603806">"ਇਸ ਐਪ ਲਈ <xliff:g id="PERM">%1$s</xliff:g> ਪਹੁੰਚ"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> \'ਤੇ ਇਸ ਐਪ ਲਈ <xliff:g id="PERM">%1$s</xliff:g> ਦੀ ਪਹੁੰਚ"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g> ਦੀਆਂ ਸਾਰੀਆਂ ਇਜਾਜ਼ਤਾਂ ਦੇਖੋ"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ਇਸ ਇਜਾਜ਼ਤ ਵਾਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਦੇਖੋ"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistant ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਦਿਖਾਓ"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ਐਪ ਨੂੰ ਨਾ ਵਰਤੇ ਜਾਣ \'ਤੇ ਇਸ ਲਈ ਦਿੱਤੀਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਹਟਾ ਦਿਓ"</string> <string name="unused_apps_label" msgid="2595428768404901064">"ਇਜਾਜ਼ਤਾਂ ਹਟਾਓ ਅਤੇ ਜਗ੍ਹਾ ਖਾਲੀ ਕਰੋ"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"ਵਰਤੋਂ ਵਿੱਚ ਨਾ ਹੋਣ \'ਤੇ, ਐਪ ਸਰਗਰਮੀ ਰੋਕੋ"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ਵਰਤੋਂ ਵਿੱਚ ਨਾ ਹੋਣ \'ਤੇ, ਐਪ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ਇਜਾਜ਼ਤਾਂ ਹਟਾਓ, ਅਸਥਾਈ ਫ਼ਾਈਲਾਂ ਮਿਟਾਓ ਅਤੇ ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ਇਜਾਜ਼ਤਾਂ ਹਟਾਓ, ਅਸਥਾਈ ਫ਼ਾਈਲਾਂ ਮਿਟਾਓ, ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ ਅਤੇ ਐਪ ਨੂੰ ਪੁਰਾਲੇਖਬੱਧ ਕਰੋ"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"ਤੁਹਾਡੀ ਡਾਟਾ ਸੁਰੱਖਿਆ ਲਈ, ਜੇ ਇਹ ਐਪ ਕੁਝ ਮਹੀਨਿਆਂ ਲਈ ਵਰਤੀ ਨਹੀਂ ਗਈ, ਤਾਂ ਇਸ ਐਪ ਲਈ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"ਤੁਹਾਡੀ ਡਾਟਾ ਸੁਰੱਖਿਆ ਲਈ, ਜੇ ਇਹ ਐਪ ਕੁਝ ਮਹੀਨਿਆਂ ਲਈ ਵਰਤੀ ਨਹੀਂ ਗਈ, ਤਾਂ ਅੱਗੇ ਦਿੱਤੀਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"ਤੁਹਾਡੀ ਡਾਟਾ ਸੁਰੱਖਿਆ ਲਈ, ਜੋ ਐਪਾਂ ਤੁਸੀਂ ਕੁਝ ਮਹੀਨਿਆਂ ਤੋਂ ਨਹੀਂ ਵਰਤੀਆਂ ਉਹਨਾਂ ਐਪਾਂ ਤੋਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ।"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ਸਾਰੀਆਂ ਫ਼ਾਈਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਦਿੱਤਾ ਗਿਆ"</string> <string name="ask_header" msgid="2633816846459944376">"ਹਰ ਵਾਰ ਪੁੱਛੋ"</string> <string name="denied_header" msgid="903209608358177654">"ਗੈਰ-ਮਨਜ਼ੂਰਸ਼ੁਦਾ"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> \'ਤੇ <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ਸਾਰੀਆਂ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਣ ਵਾਲੀਆਂ ਹੋਰ ਐਪਾਂ ਦੇਖੋ"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ਦਿਨ}one{# ਦਿਨ}other{# ਦਿਨ}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ਘੰਟਾ}one{# ਘੰਟਾ}other{# ਘੰਟੇ}}"</string> @@ -371,7 +373,7 @@ <string name="role_sms_search_keywords" msgid="8022048144395047352">"ਲਿਖਤ ਸੁਨੇਹਾ, ਲਿਖਤ ਭੇਜਣਾ, ਸੁਨੇਹੇ, ਸੁਨੇਹਾ ਭੇਜਣਾ"</string> <string name="role_emergency_label" msgid="7028825857206842366">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੰਕਟਕਾਲੀਨ ਐਪ"</string> <string name="role_emergency_short_label" msgid="2388431453335350348">"ਸੰਕਟਕਾਲੀਨ ਐਪ"</string> - <string name="role_emergency_description" msgid="5051840234887686630">"ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਤੁਹਾਡੀ ਡਾਕਟਰੀ ਜਾਣਕਾਰੀ ਰਿਕਾਰਡ ਕਰਨ ਅਤੇ ਇਸਨੂੰ ਸੰਕਟਕਾਲੀਨ ਮਦਦਗਾਰਾਂ ਤੱਕ ਪਹੁੰਚਯੋਗ ਬਣਾਉਣ ਦਿੰਦੀਆਂ ਹਨ; ਗੰਭੀਰ ਮੌਸਮੀ ਘਟਨਾਵਾਂ ਅਤੇ ਆਫ਼ਤਾਂ ਬਾਰੇ ਸੁਚੇਤਨਾਵਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ; ਤੁਹਾਨੂੰ ਮਦਦ ਦੀ ਲੋੜ ਪੈਣ \'ਤੇ ਹੋਰਾਂ ਨੂੰ ਸੂਚਿਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ"</string> + <string name="role_emergency_description" msgid="5051840234887686630">"ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਤੁਹਾਡੀ ਡਾਕਟਰੀ ਜਾਣਕਾਰੀ ਰਿਕਾਰਡ ਕਰਨ ਅਤੇ ਇਸਨੂੰ ਐਮਰਜੈਂਸੀ ਮਦਦਗਾਰਾਂ ਤੱਕ ਪਹੁੰਚਯੋਗ ਬਣਾਉਣ ਦਿੰਦੀਆਂ ਹਨ; ਬਹੁਤ ਜ਼ਿਆਦਾ ਖਰਾਬ ਮੌਸਮੀ ਘਟਨਾਵਾਂ ਅਤੇ ਆਫ਼ਤਾਂ ਬਾਰੇ ਅਲਰਟ ਪ੍ਰਾਪਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ; ਤੁਹਾਨੂੰ ਮਦਦ ਦੀ ਲੋੜ ਪੈਣ \'ਤੇ ਹੋਰਾਂ ਨੂੰ ਸੂਚਿਤ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ"</string> <string name="role_emergency_request_title" msgid="8469579020654348567">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੰਕਟਕਾਲੀਨ ਐਪ ਵਜੋਂ ਸੈੱਟ ਕਰਨਾ ਹੈ?"</string> <string name="role_emergency_request_description" msgid="131645948770262850">"ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ"</string> <string name="role_emergency_search_keywords" msgid="1920007722599213358">"ice"</string> @@ -400,9 +402,14 @@ <string name="role_app_streaming_description" msgid="7341638576226183992">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀਆਂ ਸੂਚਨਾਵਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰਨ ਅਤੇ ਤੁਹਾਡੀਆਂ ਐਪਾਂ ਨੂੰ ਕਨੈਕਟ ਕੀਤੇ ਡੀਵਾਈਸ \'ਤੇ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ।"</string> <string name="role_companion_device_computer_description" msgid="416099879217066377">"ਇਹ ਸੇਵਾ ਤੁਹਾਡੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਹੋਰ ਡੀਵਾਈਸਾਂ ਨਾਲ ਸਾਂਝਾ ਕਰਦੀ ਹੈ।"</string> <string name="role_notes_label" msgid="7451627001058089536">"ਨੋਟ-ਕਥਨਾਂ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਐਪ"</string> - <string name="role_notes_short_label" msgid="8796604147546125285">"ਨੋਟ-ਕਥਨਾਂ ਲਈ ਐਪ"</string> - <string name="role_notes_description" msgid="8496852798616883551">"ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਨੋਟ-ਕਥਨ ਲੈਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀਆਂ ਹਨ"</string> + <string name="role_notes_short_label" msgid="8796604147546125285">"ਨੋਟ ਲਈ ਐਪ"</string> + <string name="role_notes_description" msgid="8496852798616883551">"ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਨੋਟ ਲਿਖਣ ਦੀ ਸੁਵਿਧਾ ਦਿੰਦੀਆਂ ਹਨ"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ਨੋਟ-ਕਥਨ"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਾਲੇਟ ਐਪ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet ਐਪ"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"ਲੈਣ-ਦੇਣ ਦੀਆਂ ਵੱਖ-ਵੱਖ ਕਿਸਮਾਂ ਸੰਬੰਧੀ ਮਦਦ ਕਰਨ ਲਈ, ਵਾਲੇਟ ਐਪਾਂ ਤੁਹਾਡੇ ਕ੍ਰੈਡਿਟ ਅਤੇ ਵਫ਼ਾਦਾਰੀ ਕਾਰਡਾਂ, ਕਾਰ ਦੀਆਂ ਕੁੰਜੀਆਂ ਅਤੇ ਹੋਰ ਚੀਜ਼ਾਂ ਨੂੰ ਸਟੋਰ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਾਲੇਟ ਐਪ ਵਜੋਂ ਸੈੱਟ ਕਰਨਾ ਹੈ?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ"</string> <string name="request_role_current_default" msgid="738722892438247184">"ਮੌਜੂਦਾ ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਵਜੋਂ ਸੈੱਟ ਕਰੋ"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"ਇਹ ਐਪ ਹਰ ਵੇਲੇ ਆਡੀਓ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗਦੀ ਹੈ, ਉਦੋਂ ਵੀ ਜਦੋਂ ਤੁਸੀਂ ਐਪ ਦੀ ਵਰਤੋਂ ਨਾ ਕਰ ਰਹੇ ਹੋਵੋ। "<annotation id="link">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਇਜਾਜ਼ਤ ਦਿਓ।"</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਆਪਣੀ ਸਰੀਰਕ ਸਰਗਰਮੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> \'ਤੇ ਆਪਣੀ ਸਰੀਰਕ ਸਰਗਰਮੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਤਸਵੀਰਾਂ ਖਿੱਚਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ ਦੇਣਾ ਹੈ?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਤਸਵੀਰਾਂ ਖਿੱਚਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਆਪਣੇ <b><xliff:g id="DEVICE">%2$s</xliff:g></b> \'ਤੇ ਤਸਵੀਰਾਂ ਖਿੱਚਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ ਦੇਣੀ ਹੈ?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਹੀ ਐਪ ਤਸਵੀਰਾਂ ਖਿੱਚ ਸਕੇਗੀ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰ ਸਕੇਗੀ"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਤਸਵੀਰਾਂ ਖਿੱਚਣ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?"</string> @@ -552,7 +559,7 @@ <string name="safety_center_dashboard_page_title" msgid="2810774008694315854">"ਸੁਰੱਖਿਆ ਅਤੇ ਪਰਦੇਦਾਰੀ"</string> <string name="safety_center_rescan_button" msgid="4517514567809409596">"ਡੀਵਾਈਸ ਨੂੰ ਸਕੈਨ ਕਰੋ"</string> <string name="safety_center_issue_card_dismiss_button" msgid="5113965506144222402">"ਖਾਰਜ ਕਰੋ"</string> - <string name="safety_center_issue_card_dismiss_confirmation_title" msgid="2734809473425036382">"ਕੀ ਇਸ ਸੁਚੇਤਨਾ ਨੂੰ ਖਾਰਜ ਕਰਨਾ ਹੈ?"</string> + <string name="safety_center_issue_card_dismiss_confirmation_title" msgid="2734809473425036382">"ਕੀ ਇਸ ਅਲਰਟ ਨੂੰ ਖਾਰਜ ਕਰਨਾ ਹੈ?"</string> <string name="safety_center_issue_card_dismiss_confirmation_message" msgid="3775418736671093563">"ਹੋਰ ਸੁਰੱਖਿਆ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਕਿਸੇ ਵੀ ਸਮੇਂ ਆਪਣੀਆਂ ਸੁਰੱਖਿਆ ਅਤੇ ਪਰਦੇਦਾਰੀ ਸੈਟਿੰਗਾਂ ਦੀ ਸਮੀਖਿਆ ਕਰੋ"</string> <string name="safety_center_issue_card_confirm_dismiss_button" msgid="5884137843083634556">"ਖਾਰਜ ਕਰੋ"</string> <string name="safety_center_issue_card_cancel_dismiss_button" msgid="2874578798877712346">"ਰੱਦ ਕਰੋ"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ਡਾਟਾ ਸਾਂਝਾਕਰਨ ਅੱਪਡੇਟ"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"ਕੁਝ ਐਪਾਂ ਨੇ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਦੇ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਦਾ ਤਰੀਕਾ ਬਦਲ ਦਿੱਤਾ ਹੈ"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ਸੈਟਿੰਗਾਂ"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> ਵਜੇ ਪਹੁੰਚ ਕੀਤੀ ਗਈ"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"<xliff:g id="TIME_DATE">%1$s</xliff:g> ਵਜੇ ਕੱਲ੍ਹ ਪਹੁੰਚ ਕੀਤੀ ਗਈ"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> ਨੂੰ <xliff:g id="TIME_DATE_1">%2$s</xliff:g> ਵਜੇ ਪਹੁੰਚ ਕੀਤੀ ਗਈ"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ਤੁਹਾਡਾ ਇਕਹਰੀ-ਵਰਤੋਂ ਪਾਸਵਰਡ 132435 ਹੈ"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"ਪ੍ਰਤਿਬੰਧਿਤ ਸੈਟਿੰਗਾਂ"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਫ਼ਿਲਹਾਲ ਇਹ ਸੈਟਿੰਗ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"ਐਪ ਨੂੰ <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੱਤੀ ਗਈ"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"ਐਪ ਨੇ ਸੰਵੇਦਨਸ਼ੀਲ ਇਜਾਜ਼ਤ ਤੱਕ ਪਹੁੰਚ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ, ਜਿਸ ਨਾਲ ਤੁਹਾਡੀ ਨਿੱਜੀ ਅਤੇ ਵਿੱਤੀ ਜਾਣਕਾਰੀ ਜੋਖਮ ਵਿੱਚ ਪੈ ਸਕਦੀ ਹੈ।<xliff:g id="ID_1"><br><br></xliff:g>ਇਹ ਸੰਭਵ ਹੈ, ਕਿ ਐਪ ਇਸ ਪ੍ਰਤਿਬੰਧਿਤ ਇਜਾਜ਼ਤ ਤੋਂ ਬਿਨਾਂ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣ ਦੇ ਤਰੀਕੇ ਬਾਰੇ ਜਾਣੋ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ਐਪ ਨੂੰ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ <xliff:g id="ROLE_NAME">%1$s</xliff:g> ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੱਤੀ ਗਈ"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"ਐਪ ਨੇ ਸੰਵੇਦਨਸ਼ੀਲ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ, ਜਿਸ ਨਾਲ ਤੁਹਾਡੀ ਨਿੱਜੀ ਅਤੇ ਵਿੱਤੀ ਜਾਣਕਾਰੀ ਜੋਖਮ ਵਿੱਚ ਪੈ ਸਕਦੀ ਹੈ।<xliff:g id="ID_1"><br><br></xliff:g>ਇਹ ਸੰਭਵ ਹੈ, ਕਿ ਐਪ ਇਨ੍ਹਾਂ ਪ੍ਰਤਿਬੰਧਿਤ ਇਜਾਜ਼ਤਾਂ ਤੋਂ ਬਿਨਾਂ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣ ਦੇ ਤਰੀਕੇ ਬਾਰੇ ਜਾਣੋ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ਐਪ ਨੂੰ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੱਤੀ ਗਈ"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ਇਸ ਇਜਾਜ਼ਤ ਲਈ ਪਹੁੰਚ ਦੇਣ ਨਾਲ ਤੁਹਾਡੀ ਨਿੱਜੀ ਅਤੇ ਵਿੱਤੀ ਜਾਣਕਾਰੀ ਜੋਖਮ ਵਿੱਚ ਪੈ ਸਕਦੀ ਹੈ।<xliff:g id="ID_1"><br><br></xliff:g>ਇਹ ਸੰਭਵ ਹੈ, ਕਿ ਐਪ ਇਸ ਪ੍ਰਤਿਬੰਧਿਤ ਇਜਾਜ਼ਤ ਤੋਂ ਬਿਨਾਂ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ। <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣ ਦੇ ਤਰੀਕੇ ਬਾਰੇ ਜਾਣੋ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ਹੋਰ ਜਾਣੋ"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ਠੀਕ ਹੈ"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"ਇਜਾਜ਼ਤ ਸੰਬੰਧੀ ਬੇਨਤੀ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ਇਹ ਐਪ ਵਧੀਕ ਇਜਾਜ਼ਤਾਂ ਦੀ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ, ਪਰ ਸਟ੍ਰੀਮਿੰਗ ਸੈਸ਼ਨ ਵਿੱਚ ਇਜਾਜ਼ਤਾਂ ਨਹੀਂ ਦਿੱਤੀਆਂ ਜਾ ਸਕਦੀਆਂ। ਪਹਿਲਾਂ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਇਜਾਜ਼ਤ ਦਿਓ।"</string> </resources> diff --git a/PermissionController/res/values-pl-v34/strings.xml b/PermissionController/res/values-pl-v34/strings.xml index b69bf4c4f..201b9d1c7 100644 --- a/PermissionController/res/values-pl-v34/strings.xml +++ b/PermissionController/res/values-pl-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Zarządzaj dostępem aplikacji do danych dotyczących zdrowia"</string> <string name="location_settings" msgid="8863940440881290182">"Dostęp do lokalizacji"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Dotyczy aplikacji i usług. Jeśli wyłączysz to ustawienie, dane mikrofonu wciąż mogą być udostępniane podczas połączenia z numerem alarmowym"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Dotyczy aplikacji i usług"</string> </resources> diff --git a/PermissionController/res/values-pl-watch/strings.xml b/PermissionController/res/values-pl-watch/strings.xml index 1fbfdf245..0fe2421f6 100644 --- a/PermissionController/res/values-pl-watch/strings.xml +++ b/PermissionController/res/values-pl-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Nie można zmienić"</string> <string name="generic_yes" msgid="2489207724988649846">"Tak"</string> <string name="generic_cancel" msgid="2631708607129269698">"Anuluj"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Cały czas"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Gdy używasz aplikacji"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Cały czas"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Gdy używasz aplikacji"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Cały czas"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Gdy używasz aplikacji"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Cały czas"</string> </resources> diff --git a/PermissionController/res/values-pl/strings.xml b/PermissionController/res/values-pl/strings.xml index 9ed891733..41004e695 100644 --- a/PermissionController/res/values-pl/strings.xml +++ b/PermissionController/res/values-pl/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Wszystkie uprawnienia"</string> <string name="other_permissions" msgid="2901186127193849594">"Inne funkcje aplikacji"</string> <string name="permission_request_title" msgid="8790310151025020126">"Prośba o pozwolenie"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear nie obsługuje instalowania ani odinstalowywania."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Wybierz, jakie uprawnienia dostępu ma mieć <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplikacja <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> została zaktualizowana. Wybierz dla niej uprawnienia dostępu."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Anuluj"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kiedy dokładna lokalizacja jest wyłączona, aplikacje mają dostęp do Twojej przybliżonej lokalizacji"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> – dostęp"</string> <string name="app_permission_header" msgid="2951363137032603806">"Dostęp tej aplikacji do: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Aplikacja ma przyznane uprawnienie <xliff:g id="PERM">%1$s</xliff:g> na tym urządzeniu: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Zobacz wszystkie uprawnienia aplikacji <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Wyświetl wszystkie aplikacje z tym uprawnieniem"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Pokaż użycie mikrofonu w Asystencie"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Usuń uprawnienia, jeśli aplikacja jest nieużywana"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Usuń uprawnienia i zwolnij miejsce"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Wstrzymuj aktywność w aplikacji, jeśli jest nieużywana"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Zarządzaj nieużywanymi aplikacjami"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Usuń uprawnienia i pliki tymczasowe oraz zatrzymaj powiadomienia"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Usuń uprawnienia i pliki tymczasowe, zatrzymaj powiadomienia i zarchiwizuj aplikację"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Aby chronić Twoje dane, usuniemy uprawnienia tej aplikacji, jeśli nie była używana od kilku miesięcy."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Aby chronić Twoje dane, jeśli aplikacja nie będzie używana przez kilka miesięcy, usuniemy te uprawnienia: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Aby chronić Twoje dane, usunęliśmy uprawnienia aplikacji, których nie używano od kilku miesięcy."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Zezwolono na zarządzanie wszystkimi plikami"</string> <string name="ask_header" msgid="2633816846459944376">"Zawsze pytaj"</string> <string name="denied_header" msgid="903209608358177654">"Nie mają dostępu"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> na tym urządzeniu: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Zobacz więcej aplikacji z dostępem do wszystkich plików"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dzień}few{# dni}many{# dni}other{# dnia}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# godzina}few{# godziny}many{# godzin}other{# godziny}}"</string> @@ -342,7 +344,7 @@ <string name="no_apps_allowed" msgid="7718822655254468631">"Nie zezwolono żadnym aplikacjom"</string> <string name="no_apps_allowed_full" msgid="8011716991498934104">"Brak aplikacji z uprawnieniami dla wszystkich plików"</string> <string name="no_apps_allowed_scoped" msgid="4908850477787659501">"Brak aplikacji z uprawnieniami tylko dla multimediów"</string> - <string name="no_apps_denied" msgid="7663435886986784743">"Nie zabroniono żadnym aplikacjom"</string> + <string name="no_apps_denied" msgid="7663435886986784743">"Nie zabroniono dostępu żadnym aplikacjom"</string> <string name="car_permission_selected" msgid="180837028920791596">"Wybrana"</string> <string name="settings" msgid="5409109923158713323">"Ustawienia"</string> <string name="accessibility_service_dialog_title_single" msgid="7956432823014102366">"Usługa <xliff:g id="SERVICE_NAME">%s</xliff:g> ma pełny dostęp do urządzenia"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikacja do notatek"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikacje umożliwiające robienie notatek na urządzeniu"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notatki"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Domyślna aplikacja portfela"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikacja portfela cyfrowego"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aby ułatwić sobie wykonywanie różny form transakcji, w aplikacjach portfeli cyfrowych można przechowywać karty kredytowe i lojalnościowe, kluczyki do samochodu i inne rzeczy."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Ustawić aplikację <xliff:g id="APP_NAME">%1$s</xliff:g> jako domyślną aplikację portfela cyfrowego?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nie potrzebuje uprawnień"</string> <string name="request_role_current_default" msgid="738722892438247184">"Bieżąca aplikacja domyślna"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Nie pytaj ponownie"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Ustaw jako domyślną"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Zmiany w udostępnianiu danych"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Niektóre aplikacje zmieniły sposób udostępniania Twoich danych o lokalizacji"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Ustawienia"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Ostatni dostęp <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Ostatni dostęp wczoraj, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Ostatni dostęp <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Twoje hasło jednorazowe to 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ustawienie z ograniczonym dostępem"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Ze względów bezpieczeństwa to ustawienie jest obecnie niedostępne."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikacja nie otrzymała dostępu do uprawnień <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikacja wymaga dostępu do uprawnień newralgicznych, co może zagrażać Twoim danym osobowym i informacjom finansowym.<xliff:g id="ID_1"><br><br></xliff:g>Możliwe, że bez tego uprawnienia z ograniczeniami aplikacja nie będzie działać poprawnie. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Jak zezwolić na dostęp</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikacja nie otrzymała dostępu jako domyślna <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikacja wymaga dostępu do uprawnień newralgicznych, co może zagrażać Twoim danym osobowym i informacjom finansowym.<xliff:g id="ID_1"><br><br></xliff:g>Możliwe, że bez tego uprawnienia z ograniczeniami aplikacja nie będzie działać poprawnie. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Jak zezwolić na dostęp</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikacja nie otrzymała dostępu"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Dostęp do tych uprawnień może zagrażać Twoim danym osobowym i informacjom finansowym.<xliff:g id="ID_1"><br><br></xliff:g>Możliwe, że bez tych uprawnień z ograniczeniami aplikacja nie będzie działać poprawnie. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Jak zezwolić na dostęp</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Więcej informacji"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Prośba o uprawnienia została zablokowana"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ta aplikacja prosi o dodatkowe uprawnienia, ale nie można ich przyznać w trakcie sesji strumieniowania. Najpierw przyznaj te uprawnienia na telefonie."</string> </resources> diff --git a/PermissionController/res/values-pt-rBR-v34/strings.xml b/PermissionController/res/values-pt-rBR-v34/strings.xml index 6e77e0432..78bebb7a5 100644 --- a/PermissionController/res/values-pt-rBR-v34/strings.xml +++ b/PermissionController/res/values-pt-rBR-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gerenciar o acesso de apps aos dados de saúde"</string> <string name="location_settings" msgid="8863940440881290182">"Acesso ao local"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Para apps e serviços. Se esta configuração estiver desativada, os dados do microfone ainda poderão ser compartilhados quando você ligar para um número de emergência"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Para apps e serviços"</string> </resources> diff --git a/PermissionController/res/values-pt-rBR-watch/strings.xml b/PermissionController/res/values-pt-rBR-watch/strings.xml index aa3b75772..84379daa0 100644 --- a/PermissionController/res/values-pt-rBR-watch/strings.xml +++ b/PermissionController/res/values-pt-rBR-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Impossível alterar"</string> <string name="generic_yes" msgid="2489207724988649846">"Sim"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancelar"</string> + <string name="permission_access_always" msgid="2107115233573823032">"O tempo todo"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Durante o uso do app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"O tempo todo"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Durante o uso do app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"O tempo todo"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Durante o uso do app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"O tempo todo"</string> </resources> diff --git a/PermissionController/res/values-pt-rBR/strings.xml b/PermissionController/res/values-pt-rBR/strings.xml index 03089b17c..2467f5a4c 100644 --- a/PermissionController/res/values-pt-rBR/strings.xml +++ b/PermissionController/res/values-pt-rBR/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Todas as permissões"</string> <string name="other_permissions" msgid="2901186127193849594">"Outros recursos do app"</string> <string name="permission_request_title" msgid="8790310151025020126">"Solicitação de permissão"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Escolha o que o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> terá permissão para acessar"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"O app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> foi atualizado. Escolha o que esse app terá permissão para acessar."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancelar"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Apps podem acessar a localização aproximada quando o local exato está desativado"</string> <string name="app_permission_title" msgid="2090897901051370711">"Permissão para acessar <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Permitir que este app acesse: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Acesso de <xliff:g id="PERM">%1$s</xliff:g> para esse app no <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ver todas as permissões do app <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Mostrar todos os apps que têm esta permissão"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostrar uso de microfone pelo Assistente"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Remover permissões se o app não for usado"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remover permissões e liberar espaço"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausar atividade no app quando não usado"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gerenciar o app fora de uso"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remove permissões, exclui arquivos temporários e para notificações"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remover permissões, excluir arquivos temporários, parar notificações e arquivar o app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para proteger seus dados, as permissões serão removidas se o app não for usado por alguns meses."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para proteger seus dados, se o app não for usado por alguns meses, as seguintes permissões serão removidas: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para proteger seus dados, as permissões de apps que não foram usados nos últimos meses foram removidas."</string> @@ -248,12 +249,13 @@ <string name="app_permission_never_accessed_summary" msgid="401346181461975090">"Nunca acessou"</string> <string name="app_permission_never_accessed_denied_summary" msgid="6596000497490905146">"Negado/nunca acessado"</string> <string name="allowed_header" msgid="7769277978004790414">"Permitido"</string> - <string name="allowed_always_header" msgid="6455903312589013545">"Permitido sempre"</string> - <string name="allowed_foreground_header" msgid="6845655788447833353">"Permitido durante o uso"</string> + <string name="allowed_always_header" msgid="6455903312589013545">"Permitidos sempre"</string> + <string name="allowed_foreground_header" msgid="6845655788447833353">"Permitidos durante o uso"</string> <string name="allowed_storage_scoped" msgid="5383645873719086975">"Com permissão para acessar apenas mídia"</string> <string name="allowed_storage_full" msgid="5356699280625693530">"Com permissão para gerenciar todos os arquivos"</string> <string name="ask_header" msgid="2633816846459944376">"Perguntar sempre"</string> <string name="denied_header" msgid="903209608358177654">"Não permitido"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> no <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Veja mais apps que têm acesso a todos os arquivos"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dia}one{# dia}many{# dias}other{# dias}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hora}one{# hora}many{# de horas}other{# horas}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"App de notas"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps que permitem a criação de notas no dispositivo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notas"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Carteira digital padrão"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"App de carteira"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Os apps de carteira digital armazenam seus cartões de crédito e de fidelidade,as chaves do carro, entre outros itens, para agilizar suas transações."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Definir <xliff:g id="APP_NAME">%1$s</xliff:g> como seu app de carteira padrão?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nenhuma permissão necessária"</string> <string name="request_role_current_default" msgid="738722892438247184">"Padrão atual"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Não perguntar novamente"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Definir como padrão"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Atualizações do compartilhamento de dados"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Alguns apps mudaram a forma como podem compartilhar seus dados de local"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Configurações"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Último acesso: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Último acesso: ontem, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Último acesso: <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Sua senha única é 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Configuração restrita"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Para sua segurança, essa configuração está indisponível no momento."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"O app não recebeu a seguinte permissão de acesso: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"O app solicitou acesso a uma permissão sensível que pode colocar suas informações pessoais e financeiras em risco.<xliff:g id="ID_1"><br><br></xliff:g>É possível que o app não funcione corretamente sem essa permissão restrita. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Aprenda a conceder acesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"O app não recebeu o acesso para ser a escolha padrão de: <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"O app solicitou acesso a permissões sensíveis que podem colocar suas informações pessoais e financeiras em risco.<xliff:g id="ID_1"><br><br></xliff:g>É possível que o app não funcione corretamente sem essas permissões restritas. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Aprenda a conceder acesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"O app não recebeu a permissão de acesso"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"O acesso a essa permissão pode colocar suas informações pessoais e financeiras em risco.<xliff:g id="ID_1"><br><br></xliff:g>É possível que o app não funcione corretamente sem essa permissão restrita. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Aprenda a conceder acesso</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Saiba mais"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Solicitação de permissão suprimida"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo smartphone primeiro."</string> </resources> diff --git a/PermissionController/res/values-pt-rPT-v34/strings.xml b/PermissionController/res/values-pt-rPT-v34/strings.xml index 2f7ce1be2..a4d6bd83b 100644 --- a/PermissionController/res/values-pt-rPT-v34/strings.xml +++ b/PermissionController/res/values-pt-rPT-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Faça a gestão do acesso de apps a dados de saúde"</string> <string name="location_settings" msgid="8863940440881290182">"Acesso à localização"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Para apps e serviços. Se esta definição estiver desativada, os dados do microfone ainda podem ser partilhados quando ligar para um número de emergência"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Para apps e serviços"</string> </resources> diff --git a/PermissionController/res/values-pt-rPT-watch/strings.xml b/PermissionController/res/values-pt-rPT-watch/strings.xml index 3c3a88806..60b1f5f4d 100644 --- a/PermissionController/res/values-pt-rPT-watch/strings.xml +++ b/PermissionController/res/values-pt-rPT-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Impossív. alterar"</string> <string name="generic_yes" msgid="2489207724988649846">"Sim"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancelar"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Sempre"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Quando usar a app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Sempre"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Quando usar a app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Sempre"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Quando usar a app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Sempre"</string> </resources> diff --git a/PermissionController/res/values-pt-rPT/strings.xml b/PermissionController/res/values-pt-rPT/strings.xml index 437805f95..2e906d29f 100644 --- a/PermissionController/res/values-pt-rPT/strings.xml +++ b/PermissionController/res/values-pt-rPT/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Todas as autorizações"</string> <string name="other_permissions" msgid="2901186127193849594">"Outras capacidades de aplicações"</string> <string name="permission_request_title" msgid="8790310151025020126">"Pedido de autorização"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Escolher a que conteúdos permite que o <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"O <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> foi atualizado. Escolha a que conteúdos permite que esta app aceda."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancelar"</string> @@ -195,18 +193,21 @@ <string name="app_permission_button_deny" msgid="6016454069832050300">"Não permitir"</string> <string name="precise_image_description" msgid="6349638632303619872">"Localização exata"</string> <string name="approximate_image_description" msgid="938803699637069884">"Localização aproximada"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Usar localização exata"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Localização exata"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Quando a localização exata está desativada, as apps podem aceder à sua localização aproximada"</string> <string name="app_permission_title" msgid="2090897901051370711">"Autorização de <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Acesso desta app a <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Acesso a <xliff:g id="PERM">%1$s</xliff:g> para esta app no dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ver todas as autorizações da app <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Ver todas as apps com esta autorização"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostrar utilização do microfone do assistente"</string> <string name="unused_apps_category_title" msgid="2988455616845243901">"Definições de apps não usadas"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"Remover autorizações se a app não for utilizada"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remover autorizações e libertar espaço"</string> - <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausar atividade de apps, se não usadas"</string> - <string name="unused_apps_summary" msgid="8839466950318403115">"Remova autorizações, elimine ficheiros temporários e pare notificações"</string> + <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausar atividade de apps se não usadas"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gerir app, se não for usada"</string> + <string name="unused_apps_summary" msgid="8839466950318403115">"Remover autorizações, eliminar ficheiros temporários e parar notificações"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove autorizações, elimina ficheiros temporários, pára notificações e arquiva a app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para proteger os seus dados, as autorizações desta app serão removidas se a mesma não for utilizada durante alguns meses."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para proteger os seus dados, se a app não for utilizada há alguns meses, serão removidas as seguintes autorizações: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para proteger os seus dados, foram removidas as autorizações para as apps que não utiliza há alguns meses."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Com autorização para gerir todos os ficheiros"</string> <string name="ask_header" msgid="2633816846459944376">"Perguntar sempre"</string> <string name="denied_header" msgid="903209608358177654">"Não permitidas"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> no dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Veja mais apps que podem aceder a todos os ficheiros"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dia}many{# dias}other{# dias}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hora}many{# horas}other{# horas}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"App de notas"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps que lhe permitem tirar notas no seu dispositivo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notas"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"App de carteira predefinida"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"App de carteira"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"As apps de carteira podem armazenar os seus cartões de crédito e de fidelidade, as chaves do carro, entre outras coisas, para ajudar em várias formas de transações."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Definir a app <xliff:g id="APP_NAME">%1$s</xliff:g> como a sua app de carteira predefinida?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Não são necessárias autorizações"</string> <string name="request_role_current_default" msgid="738722892438247184">"Predefinição atual"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Não perguntar novamente"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Definir como predef."</string> @@ -514,7 +521,7 @@ <string name="permgroupupgraderequestdetail_camera" msgid="6642747548010962597">"Esta app quer tirar fotos e gravar vídeos sempre, mesmo quando não a está a utilizar. "<annotation id="link">"Permita-o nas Definições."</annotation></string> <string name="permgrouprequest_calllog" msgid="2065327180175371397">"Permitir que a app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda aos registos de chamadas do seu telemóvel?"</string> <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"Permitir que a app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda aos registos de chamadas telefónicas no <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_phone" msgid="1829234136997316752">"Permitir que a app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> faça e gira chamadas telefónicas?"</string> + <string name="permgrouprequest_phone" msgid="1829234136997316752">"Permitir que a app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> passe a fazer e gerir chamadas telefónicas?"</string> <string name="permgrouprequest_device_aware_phone" msgid="4389610977195521813">"Permitir que a app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> faça e gira chamadas no <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_sensors" msgid="4397358316850652235">"Permitir que a app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda aos dados de sensores acerca dos seus sinais vitais?"</string> <string name="permgrouprequest_device_aware_sensors" msgid="1900598688488188225">"Permitir que a app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda aos dados de sensores sobre os seus sinais vitais no <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> @@ -612,9 +619,9 @@ <string name="mic_toggle_description" msgid="9163104307990677157">"Para apps e serviços. Se esta definição estiver desativada, os dados do microfone ainda podem ser partilhados quando ligar para um número de emergência."</string> <string name="location_settings_subtitle" msgid="2328360561197430695">"Veja as apps e os serviços que têm acesso à localização"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Mostrar acesso à área de transferência"</string> - <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Apresente uma mensagem quando as apps acedem a texto, imagens ou outro conteúdo que copiou"</string> + <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Mostra uma mensagem quando as apps acedem a texto, imagens ou outro conteúdo que copiou"</string> <string name="show_password_title" msgid="2877269286984684659">"Mostrar palavras-passe"</string> - <string name="show_password_summary" msgid="1110166488865981610">"Apresente rapidamente os carateres ao escrever"</string> + <string name="show_password_summary" msgid="1110166488865981610">"Mostra brevemente os carateres ao escrever"</string> <string name="permission_rationale_message_location" msgid="2153841534298068414">"Esta app declarou que pode partilhar dados de localização com terceiros"</string> <string name="permission_rationale_location_title" msgid="2404797182678793506">"Localização e partilha de dados"</string> <string name="permission_rationale_data_sharing_source_title" msgid="6874604543125814316">"Qual é a origem das informações da partilha de dados"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Atualizações da partilha de dados"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Algumas apps alteraram a forma como podem partilhar os seus dados de localização"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Definições"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Acedido à(s) <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Acedido ontem à(s) <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Acedido a <xliff:g id="TIME_DATE_0">%1$s</xliff:g> à(s) <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"A sua palavra-passe de utilização única é 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Definição restrita"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Para sua segurança, esta definição está indisponível atualmente."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"O acesso a <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> foi negado à app"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"A app pediu acesso a uma autorização confidencial que pode pôr em risco as suas informações pessoais e financeiras.<xliff:g id="ID_1"><br><br></xliff:g>É possível que a app não funcione corretamente sem esta autorização restrita. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saiba como permitir o acesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"O acesso à função predefinida <xliff:g id="ROLE_NAME">%1$s</xliff:g> foi negado à app"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"A app pediu acesso a autorizações confidenciais que podem pôr em risco as suas informações pessoais e financeiras.<xliff:g id="ID_1"><br><br></xliff:g>É possível que a app não funcione corretamente sem estas autorizações restritas. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saiba como permitir o acesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"O acesso foi negado à app"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"O acesso a esta autorização pode pôr em risco as suas informações pessoais e financeiras.<xliff:g id="ID_1"><br><br></xliff:g>É possível que a app não funcione corretamente sem esta autorização restrita. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Saiba como permitir o acesso</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Saber mais"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Pedido de autorização suprimido"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Esta app está a pedir autorizações adicionais, mas não é possível conceder autorizações numa sessão de streaming. Comece por conceder a autorização no seu telemóvel."</string> </resources> diff --git a/PermissionController/res/values-pt-v34/strings.xml b/PermissionController/res/values-pt-v34/strings.xml index 6e77e0432..78bebb7a5 100644 --- a/PermissionController/res/values-pt-v34/strings.xml +++ b/PermissionController/res/values-pt-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gerenciar o acesso de apps aos dados de saúde"</string> <string name="location_settings" msgid="8863940440881290182">"Acesso ao local"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Para apps e serviços. Se esta configuração estiver desativada, os dados do microfone ainda poderão ser compartilhados quando você ligar para um número de emergência"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Para apps e serviços"</string> </resources> diff --git a/PermissionController/res/values-pt-watch/strings.xml b/PermissionController/res/values-pt-watch/strings.xml index aa3b75772..84379daa0 100644 --- a/PermissionController/res/values-pt-watch/strings.xml +++ b/PermissionController/res/values-pt-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Impossível alterar"</string> <string name="generic_yes" msgid="2489207724988649846">"Sim"</string> <string name="generic_cancel" msgid="2631708607129269698">"Cancelar"</string> + <string name="permission_access_always" msgid="2107115233573823032">"O tempo todo"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Durante o uso do app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"O tempo todo"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Durante o uso do app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"O tempo todo"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Durante o uso do app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"O tempo todo"</string> </resources> diff --git a/PermissionController/res/values-pt/strings.xml b/PermissionController/res/values-pt/strings.xml index 03089b17c..2467f5a4c 100644 --- a/PermissionController/res/values-pt/strings.xml +++ b/PermissionController/res/values-pt/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Todas as permissões"</string> <string name="other_permissions" msgid="2901186127193849594">"Outros recursos do app"</string> <string name="permission_request_title" msgid="8790310151025020126">"Solicitação de permissão"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Escolha o que o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> terá permissão para acessar"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"O app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> foi atualizado. Escolha o que esse app terá permissão para acessar."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Cancelar"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Apps podem acessar a localização aproximada quando o local exato está desativado"</string> <string name="app_permission_title" msgid="2090897901051370711">"Permissão para acessar <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Permitir que este app acesse: <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Acesso de <xliff:g id="PERM">%1$s</xliff:g> para esse app no <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ver todas as permissões do app <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Mostrar todos os apps que têm esta permissão"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Mostrar uso de microfone pelo Assistente"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Remover permissões se o app não for usado"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Remover permissões e liberar espaço"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausar atividade no app quando não usado"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gerenciar o app fora de uso"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remove permissões, exclui arquivos temporários e para notificações"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remover permissões, excluir arquivos temporários, parar notificações e arquivar o app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para proteger seus dados, as permissões serão removidas se o app não for usado por alguns meses."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para proteger seus dados, se o app não for usado por alguns meses, as seguintes permissões serão removidas: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para proteger seus dados, as permissões de apps que não foram usados nos últimos meses foram removidas."</string> @@ -248,12 +249,13 @@ <string name="app_permission_never_accessed_summary" msgid="401346181461975090">"Nunca acessou"</string> <string name="app_permission_never_accessed_denied_summary" msgid="6596000497490905146">"Negado/nunca acessado"</string> <string name="allowed_header" msgid="7769277978004790414">"Permitido"</string> - <string name="allowed_always_header" msgid="6455903312589013545">"Permitido sempre"</string> - <string name="allowed_foreground_header" msgid="6845655788447833353">"Permitido durante o uso"</string> + <string name="allowed_always_header" msgid="6455903312589013545">"Permitidos sempre"</string> + <string name="allowed_foreground_header" msgid="6845655788447833353">"Permitidos durante o uso"</string> <string name="allowed_storage_scoped" msgid="5383645873719086975">"Com permissão para acessar apenas mídia"</string> <string name="allowed_storage_full" msgid="5356699280625693530">"Com permissão para gerenciar todos os arquivos"</string> <string name="ask_header" msgid="2633816846459944376">"Perguntar sempre"</string> <string name="denied_header" msgid="903209608358177654">"Não permitido"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> no <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Veja mais apps que têm acesso a todos os arquivos"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dia}one{# dia}many{# dias}other{# dias}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hora}one{# hora}many{# de horas}other{# horas}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"App de notas"</string> <string name="role_notes_description" msgid="8496852798616883551">"Apps que permitem a criação de notas no dispositivo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notas"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Carteira digital padrão"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"App de carteira"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Os apps de carteira digital armazenam seus cartões de crédito e de fidelidade,as chaves do carro, entre outros itens, para agilizar suas transações."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Definir <xliff:g id="APP_NAME">%1$s</xliff:g> como seu app de carteira padrão?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nenhuma permissão necessária"</string> <string name="request_role_current_default" msgid="738722892438247184">"Padrão atual"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Não perguntar novamente"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Definir como padrão"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Atualizações do compartilhamento de dados"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Alguns apps mudaram a forma como podem compartilhar seus dados de local"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Configurações"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Último acesso: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Último acesso: ontem, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Último acesso: <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Sua senha única é 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Configuração restrita"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Para sua segurança, essa configuração está indisponível no momento."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"O app não recebeu a seguinte permissão de acesso: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"O app solicitou acesso a uma permissão sensível que pode colocar suas informações pessoais e financeiras em risco.<xliff:g id="ID_1"><br><br></xliff:g>É possível que o app não funcione corretamente sem essa permissão restrita. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Aprenda a conceder acesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"O app não recebeu o acesso para ser a escolha padrão de: <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"O app solicitou acesso a permissões sensíveis que podem colocar suas informações pessoais e financeiras em risco.<xliff:g id="ID_1"><br><br></xliff:g>É possível que o app não funcione corretamente sem essas permissões restritas. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Aprenda a conceder acesso</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"O app não recebeu a permissão de acesso"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"O acesso a essa permissão pode colocar suas informações pessoais e financeiras em risco.<xliff:g id="ID_1"><br><br></xliff:g>É possível que o app não funcione corretamente sem essa permissão restrita. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Aprenda a conceder acesso</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Saiba mais"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Solicitação de permissão suprimida"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo smartphone primeiro."</string> </resources> diff --git a/PermissionController/res/values-ro-v34/strings.xml b/PermissionController/res/values-ro-v34/strings.xml index e57e8c91a..cf7e275a1 100644 --- a/PermissionController/res/values-ro-v34/strings.xml +++ b/PermissionController/res/values-ro-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Gestionează accesul aplicației la datele despre sănătate"</string> <string name="location_settings" msgid="8863940440881290182">"Accesul la locație"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Pentru aplicații și servicii. Chiar dacă setarea este dezactivată, datele de la microfon pot fi trimise când apelezi un număr de urgență."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Pentru aplicații și servicii"</string> </resources> diff --git a/PermissionController/res/values-ro-watch/strings.xml b/PermissionController/res/values-ro-watch/strings.xml index 2b5702c73..01b6310df 100644 --- a/PermissionController/res/values-ro-watch/strings.xml +++ b/PermissionController/res/values-ro-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Nu se poate modif"</string> <string name="generic_yes" msgid="2489207724988649846">"Da"</string> <string name="generic_cancel" msgid="2631708607129269698">"Anulează"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Tot timpul"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Când folosești aplicația"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Tot timpul"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Când folosești aplicația"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Tot timpul"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Când folosești aplicația"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Tot timpul"</string> </resources> diff --git a/PermissionController/res/values-ro/strings.xml b/PermissionController/res/values-ro/strings.xml index b4abb4142..6767a3fcf 100644 --- a/PermissionController/res/values-ro/strings.xml +++ b/PermissionController/res/values-ro/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Toate permisiunile"</string> <string name="other_permissions" msgid="2901186127193849594">"Alte funcții ale aplicației"</string> <string name="permission_request_title" msgid="8790310151025020126">"Solicitare de permisiune"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Acțiunile Instalează/Dezinstalează nu sunt acceptate pe Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Alege ce va putea accesa <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplicația <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> a fost actualizată. Alege ce va putea accesa această aplicație."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Anulează"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Când locația exactă este dezactivată, aplicațiile îți pot accesa locația aproximativă"</string> <string name="app_permission_title" msgid="2090897901051370711">"Permisiune <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Accesul la <xliff:g id="PERM">%1$s</xliff:g> pentru această aplicație"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Acces de <xliff:g id="PERM">%1$s</xliff:g> pentru această aplicație pe <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Vezi toate permisiunile aplicației <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Vezi toate aplicațiile cu această permisiune"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Afișează datele de utilizare a microfonului cu Asistentul"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Elimină permisiunile dacă aplicația nu este folosită"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Revocă permisiunile și eliberează spațiu"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Întrerupe activitatea în aplicațiile nefolosite"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Gestionează aplicația dacă nu e folosită"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Revocă permisiunile, șterge fișierele temporare și oprește notificările"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Elimină permisiunile, șterge fișierele temporare, oprește notificările și arhivează aplicația"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Pentru a-ți proteja datele, se vor elimina permisiunile pentru această aplicație dacă nu este folosită câteva luni."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Pentru a-ți proteja datele, dacă aplicația nu este folosită câteva luni, se vor elimina următoarele permisiuni: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Pentru a-ți proteja datele, s-au eliminat permisiunile din aplicațiile pe care nu le-ai folosit de câteva luni."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Permisiunea de a gestiona toate fișierele"</string> <string name="ask_header" msgid="2633816846459944376">"Întreabă de fiecare dată"</string> <string name="denied_header" msgid="903209608358177654">"Nepermise"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> pe <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Vezi mai multe aplicații care pot accesa toate fișierele"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{O zi}few{# zile}other{# de zile}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# oră}few{# ore}other{# de ore}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplicația pentru note"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplicații cu ajutorul cărora poți să iei notițe pe dispozitiv"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notițe"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Aplicația portofel prestabilită"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplicație portofel"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplicațiile portofel pot să stocheze credit și carduri de fidelitate, chei de mașină și alte date, pentru a simplifica diferite tipuri de tranzacții."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Setezi <xliff:g id="APP_NAME">%1$s</xliff:g> ca aplicație portofel prestabilită?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nu sunt necesare permisiuni"</string> <string name="request_role_current_default" msgid="738722892438247184">"Aplicația prestabilită actuală"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Nu mai întreba"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Setează ca prestabilită"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Actualizări privind permiterea accesului la date"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Unele aplicații au schimbat modul în care pot permite accesul la datele tale privind locațiile"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Setări"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Data accesării: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Data accesării: ieri, <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Data accesării: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Parola ta unică este 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Setare restricționată"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Pentru securitatea ta, setarea este momentan indisponibilă."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Accesul aplicației la <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> a fost refuzat"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplicația a solicitat acces la o permisiune de accesare a informațiilor sensibile care îți poate pune în pericol informațiile financiare și cu caracter personal.<xliff:g id="ID_1"><br><br></xliff:g>Este posibil ca aplicația să nu funcționeze corect fără această permisiune restricționată. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Află cum să permiți accesul</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Accesul aplicației pentru a deveni <xliff:g id="ROLE_NAME">%1$s</xliff:g> prestabilită a fost refuzat"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplicația a solicitat acces la permisiuni de accesare a informațiilor sensibile care îți pot pune în pericol informațiile financiare și cu caracter personal.<xliff:g id="ID_1"><br><br></xliff:g>Este posibil ca aplicația să nu funcționeze corect fără aceste permisiuni restricționate. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Află cum să permiți accesul</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Accesul aplicației a fost refuzat"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Accesul la această permisiune îți poate pune în pericol informațiile financiare și cu caracter personal.<xliff:g id="ID_1"><br><br></xliff:g>Este posibil ca aplicația să nu funcționeze corect fără această permisiune restricționată. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Află cum să permiți accesul</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Află mai multe"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Solicitarea de permisiune s-a suprimat"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Aplicația solicită permisiuni suplimentare, dar acestea nu pot fi acordate într-o sesiune de streaming. Acordă permisiunea întâi pe telefon."</string> </resources> diff --git a/PermissionController/res/values-ru-v34/strings.xml b/PermissionController/res/values-ru-v34/strings.xml index 64a927b69..228979029 100644 --- a/PermissionController/res/values-ru-v34/strings.xml +++ b/PermissionController/res/values-ru-v34/strings.xml @@ -17,11 +17,10 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="security_privacy_brand_name" msgid="7303621734258440812">"Защита и конфиденциальность"</string> + <string name="security_privacy_brand_name" msgid="7303621734258440812">"Безопасность и конфиденциальность"</string> <string name="privacy_subpage_controls_header" msgid="4152396976713749322">"Настройки"</string> <string name="health_connect_title" msgid="2132233890867430855">"Здоровье и спорт"</string> <string name="health_connect_summary" msgid="815473513776882296">"Настроить доступ приложений к данным о здоровье"</string> <string name="location_settings" msgid="8863940440881290182">"Доступ к геоданным"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Для приложений и сервисов. Даже если эта функция отключена, данные микрофона могут передаваться при звонке на номер экстренной службы."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Для приложений и сервисов"</string> </resources> diff --git a/PermissionController/res/values-ru-watch/strings.xml b/PermissionController/res/values-ru-watch/strings.xml index a39697ff2..c7f4fd885 100644 --- a/PermissionController/res/values-ru-watch/strings.xml +++ b/PermissionController/res/values-ru-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Нельзя изменить"</string> <string name="generic_yes" msgid="2489207724988649846">"Да"</string> <string name="generic_cancel" msgid="2631708607129269698">"Отмена"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Всегда"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"При использовании"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Всегда"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"При использовании"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Всегда"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"При использовании"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Всегда"</string> </resources> diff --git a/PermissionController/res/values-ru/strings.xml b/PermissionController/res/values-ru/strings.xml index ee9ccfb2b..d38cf6189 100644 --- a/PermissionController/res/values-ru/strings.xml +++ b/PermissionController/res/values-ru/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Все разрешения"</string> <string name="other_permissions" msgid="2901186127193849594">"Что ещё может приложение"</string> <string name="permission_request_title" msgid="8790310151025020126">"Запрос разрешений"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Wear OS"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Установка и удаление не поддерживаются в Wear OS."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Выберите разрешения для приложения <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Приложение <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> обновлено. Выберите разрешения для него."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Отмена"</string> @@ -195,10 +193,11 @@ <string name="app_permission_button_deny" msgid="6016454069832050300">"Запретить"</string> <string name="precise_image_description" msgid="6349638632303619872">"Точное местоположение"</string> <string name="approximate_image_description" msgid="938803699637069884">"Приблизительное местоположение"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Использовать точное местоположение"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Точное местоположение"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Если определение точного местоположения отключено, приложения могут использовать данные о примерном местоположении устройства"</string> <string name="app_permission_title" msgid="2090897901051370711">"Разрешение \"<xliff:g id="PERM">%1$s</xliff:g>\""</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: доступ для этого приложения"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Разрешение \"<xliff:g id="PERM">%1$s</xliff:g>\" для этого приложения на устройстве \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Все разрешения приложения \"<xliff:g id="APP">%1$s</xliff:g>\""</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Все приложения с этим разрешением"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Показывать сведения об использовании микрофона Ассистентом"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Отзывать разрешения, если приложение не используется"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Удалять разрешения и освобождать место"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Приостановить работу в неактивный период"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Приостановить работу в неактивный период"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Удалить разрешения и временные файлы, прекратить отправку уведомлений"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Удалить разрешения и временные файлы, прекратить отправку уведомлений и перенести приложение в архив"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Для защиты ваших данных мы отзовем разрешения, предоставленные этому приложению, если вы не будете пользоваться им несколько месяцев."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Если вы не будете пользоваться приложением несколько месяцев, в целях защиты ваших данных мы отзовем следующие разрешения: <xliff:g id="PERMS">%1$s</xliff:g>."</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"В целях защиты ваших данных мы отозвали разрешения для приложений, которыми вы не пользовались несколько месяцев."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Приложения с доступом ко всем файлам"</string> <string name="ask_header" msgid="2633816846459944376">"Спрашивать каждый раз"</string> <string name="denied_header" msgid="903209608358177654">"Запрещено"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> на устройстве \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\""</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Ещё приложения с доступом ко всем файлам"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 день}one{# день}few{# дня}many{# дней}other{# дня}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# час}one{# час}few{# часа}many{# часов}other{# часа}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Приложение для заметок"</string> <string name="role_notes_description" msgid="8496852798616883551">"Приложения для написания заметок на вашем устройстве"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"заметки"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Кошелек по умолчанию"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Приложение-кошелек"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"В приложении-кошельке можно хранить кредитные карты, карты постоянного клиента, автомобильные ключи и другие цифровые продукты. С его помощью удобнее проводить различные типы транзакций."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Использовать приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" как кошелек по умолчанию?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Разрешения не требуются."</string> <string name="request_role_current_default" msgid="738722892438247184">"Используется по умолчанию"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Больше не спрашивать"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"По умолчанию"</string> @@ -549,7 +556,7 @@ <string name="blocked_sensor_summary" msgid="4443707628305027375">"Для приложений и сервисов"</string> <string name="blocked_mic_summary" msgid="8960466941528458347">"Данные микрофона могут передаваться при звонке на номер экстренной службы"</string> <string name="blocked_sensor_button_label" msgid="6742092634984289658">"Изменить"</string> - <string name="safety_center_dashboard_page_title" msgid="2810774008694315854">"Защита и конфиденциальность"</string> + <string name="safety_center_dashboard_page_title" msgid="2810774008694315854">"Защита и конфиденциальность"</string> <string name="safety_center_rescan_button" msgid="4517514567809409596">"Сканировать устройство"</string> <string name="safety_center_issue_card_dismiss_button" msgid="5113965506144222402">"Закрыть"</string> <string name="safety_center_issue_card_dismiss_confirmation_title" msgid="2734809473425036382">"Закрыть оповещение?"</string> @@ -560,7 +567,7 @@ <string name="safety_status_preference_title_and_summary_content_description" msgid="3511373256505058464">"Статус безопасности и конфиденциальности. <xliff:g id="OVERALL_SAFETY_STATUS">%1$s</xliff:g>. <xliff:g id="SUMMARY_OF_DEVICE_STATUS">%2$s</xliff:g>"</string> <string name="security_settings" msgid="3808106921175271317">"Настройки безопасности"</string> <string name="sensor_permissions_qs" msgid="1022267900031317472">"Разрешения"</string> - <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Защита и конфиденциальность"</string> + <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Безопасность и конфиденциальность"</string> <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Проверьте статус."</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Ваши настройки конфиденциальности"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"Другие настройки"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Обновление сведений о передаче данных"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Некоторые приложения изменили подход к передаче данных о вашем местоположении."</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Настройки"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Последний доступ: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Последний доступ вчера: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Последний доступ: <xliff:g id="TIME_DATE_0">%1$s</xliff:g>, <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Ваш одноразовый код: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Настройки с ограниченным доступом"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"В целях безопасности эти настройки пока недоступны."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Для приложения заблокировано разрешение \"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>\""</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Приложение запрашивает разрешение на доступ к конфиденциальной информации. Если вы предоставите его, ваши личные и финансовые данные могут оказаться под угрозой.<xliff:g id="ID_1"><br><br></xliff:g>Без такого разрешения приложение может работать неправильно. Узнайте, <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>как предоставить доступ к данным</a>."</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Запрещено использовать приложение в качестве стандартного в категории \"<xliff:g id="ROLE_NAME">%1$s</xliff:g>\""</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Приложение запрашивает разрешения на доступ к конфиденциальной информации. Если вы предоставите их, ваши личные и финансовые данные могут оказаться под угрозой.<xliff:g id="ID_1"><br><br></xliff:g>Без таких разрешений приложение может работать неправильно. Узнайте, <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>как предоставить доступ к данным</a>."</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Доступ запрещен"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Если вы предоставите это разрешение, ваши личные и финансовые данные могут оказаться под угрозой.<xliff:g id="ID_1"><br><br></xliff:g>Без него приложение может работать неправильно. Узнайте, <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>как предоставить доступ к данным</a>."</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Подробнее"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ОК"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Запрос разрешений заблокирован"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Это приложение запрашивает дополнительные разрешения, которые невозможно предоставить во время трансляции на устройство. Сначала откройте доступ на телефоне."</string> </resources> diff --git a/PermissionController/res/values-si-v34/strings.xml b/PermissionController/res/values-si-v34/strings.xml index 26121467a..a4c016704 100644 --- a/PermissionController/res/values-si-v34/strings.xml +++ b/PermissionController/res/values-si-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"සෞඛ්ය දත්ත වෙත යෙදුම් ප්රවේශය කළමනාකරණය කරන්න"</string> <string name="location_settings" msgid="8863940440881290182">"ස්ථාන ප්රවේශය"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"යෙදුම් සහ සේවා සඳහා. මෙම සැකසීම ක්රියාවිරහිත නම්, ඔබ හදිසි ඇමතුම් අංකයක් අමතන විට මයික්රෆෝනයේ දත්ත තවම බෙදා ගත හැක."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"යෙදුම් සහ සේවා සඳහා"</string> </resources> diff --git a/PermissionController/res/values-si-watch/strings.xml b/PermissionController/res/values-si-watch/strings.xml index 48c5164f6..a6292c8c3 100644 --- a/PermissionController/res/values-si-watch/strings.xml +++ b/PermissionController/res/values-si-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"වෙනස් කළ නොහැකිය"</string> <string name="generic_yes" msgid="2489207724988649846">"ඔව්"</string> <string name="generic_cancel" msgid="2631708607129269698">"අවලංගු කරන්න"</string> + <string name="permission_access_always" msgid="2107115233573823032">"සෑම විටම"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"යෙදුම භාවිතා කරන අතරේ"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"සෑම විටම"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"යෙදුම භාවිතා කරන අතරේ"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"සෑම විටම"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"යෙදුම භාවිතා කරන අතරේ"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"සෑම විටම"</string> </resources> diff --git a/PermissionController/res/values-si/strings.xml b/PermissionController/res/values-si/strings.xml index fc722dec7..dcf525c11 100644 --- a/PermissionController/res/values-si/strings.xml +++ b/PermissionController/res/values-si/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"සියලු අවසර"</string> <string name="other_permissions" msgid="2901186127193849594">"වෙනත් යෙදුම් හැකියාවන්"</string> <string name="permission_request_title" msgid="8790310151025020126">"අවසර ඉල්ලීම"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear මත ස්ථාපන/අස්ථාපනය ක්රියා සහාය දක්වන්නේ නැත."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> හට පිවිසීමට ඉඩ දෙන දේ තෝරන්න"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> යාවත්කාලීන කර ඇත. මෙම යෙදුමට පිවිසීමට ඉඩ දෙන දේ තෝරන්න."</string> <string name="review_button_cancel" msgid="2191147944056548886">"අවලංගු කරන්න"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"නිශ්චිත ස්ථානය ක්රියාවිරහිත විට, යෙදුම්වලට ඔබගේ දළ ස්ථානයට ප්රවේශ විය හැකිය"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> අවසරය"</string> <string name="app_permission_header" msgid="2951363137032603806">"මෙම යෙදුම සඳහා <xliff:g id="PERM">%1$s</xliff:g> ප්රවේශය"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> මත මෙම යෙදුම සඳහා <xliff:g id="PERM">%1$s</xliff:g> ප්රවේශය"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"සියලුම <xliff:g id="APP">%1$s</xliff:g> අවසර බලන්න"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"මෙම අවසරය සහිත සියලුම යෙදුම් බලන්න"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"සහායක මයික්රෆෝන භාවිතය පෙන්වන්න"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"යෙදුම භාවිත කර නැති නම් අවසර ඉවත් කරන්න"</string> <string name="unused_apps_label" msgid="2595428768404901064">"අවසර ඉවත් කරන්න සහ ඉඩ හිස් කරන්න"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"භාවිත නොකළේ නම් යෙදුම් ක්රියාකාරකම් විරාම කරන්න"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"යෙදුම භාවිතා නොකළේ නම් කළමනාකරණය කරන්න"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"අවසර ඉවත් කරන්න, තාවකාලික ගොනු මකන්න සහ දැනුම්දීම් නවත්වන්න"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"අවසර ඉවත් කරන්න, තාවකාලික ගොනු මකා දමන්න, දැනුම්දීම් නවත්වන්න, සහ යෙදුම ලේඛනාරක්ෂණය කරන්න"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"ඔබගේ දත්ත ආරක්ෂා කිරීම සඳහා, යෙදුම මාස කිහිපයක් භාවිතා නොකරන්නේ නම් මෙම යෙදුම සඳහා අවසර ඉවත් කරනු ලැබේ."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"ඔබගේ දත්ත ආරක්ෂා කිරීම සඳහා, යෙදුම මාස කිහිපයක් භාවිතා නොකරන්නේ නම් පහත අවසර ඉවත් කරනු ලැබේ: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"ඔබේ දත්ත ආරක්ෂා කිරීමට, ඔබ මාස කීපයක් තුළ භාවිත කර නැති යෙදුම්වලින් අවසර ඉවත් කර ඇත"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"සියලු පාලන කළමනාකරණය කිරීමට ඉඩ දී ඇත"</string> <string name="ask_header" msgid="2633816846459944376">"සෑම විටම ඉල්ලන්න"</string> <string name="denied_header" msgid="903209608358177654">"ඉඩ නොදේ"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> මත <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"සියලු ගොනු වෙත ප්රවේශ විය හැකි තව යෙදුම් බලන්න"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{දින 1ක්}one{දින #ක්}other{දින #ක්}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{පැය #ක්}one{පැය #ක්}other{පැය #ක්}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"සටහන් යෙදුම"</string> <string name="role_notes_description" msgid="8496852798616883551">"ඔබේ උපාංගයෙහි සටහන් ගැනීමට ඔබට ඉඩ දෙන යෙදුම්"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"සටහන්"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"පෙරනිමි පසුම්බි යෙදුම"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"පසුම්බි යෙදුම"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"පසුම්බි යෙදුම්වලට විවිධ ආකාරයේ ගනුදෙනුවලට උදවු කිරීමට ඔබේ ණය සහ ලැදියා කාඩ්පත්, මෝටර් රථ යතුරු සහ වෙනත් දේවල් ගබඩා කළ හැක."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"ඔබේ පෙරනිමි පසුම්බි යෙදුම ලෙස <xliff:g id="APP_NAME">%1$s</xliff:g> සකසන්න ද?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"අවසර අවශ්ය නැත"</string> <string name="request_role_current_default" msgid="738722892438247184">"වත්මන් පෙරනිමිය"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"නැවත නොඅසන්න"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"පෙරනිමි ලෙස සකසන්න"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"දත්ත බෙදා ගැනීමේ යාවත්කාලීන"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"සමහර යෙදුම් ඒවා ඔබේ ස්ථාන දත්ත බෙදා ගත හැකි ආකාරය වෙනස් කර ඇත"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"සැකසීම්"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"ප්රවේශ වූයේ <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"ප්රවේශ වූයේ ඊයේ <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"ප්රවේශ වූයේ <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ඔබේ එක් වරක මුරපදය 132435 වේ"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"සීමා කළ සැකසීම"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"ඔබේ ආරක්ෂාව සඳහා, මෙම සැකසීම දැනට නොමැත."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"යෙදුම <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> වෙත ප්රවේශය ප්රතික්ෂේප කරන ලදි"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"යෙදුම ඔබේ පුද්ගලික සහ මූල්ය තොරතුරු අවදානමට ලක් කළ හැකි සංවේදී අවසරයකට ප්රවේශය ඉල්ලා ඇත.<xliff:g id="ID_1"><br><br></xliff:g>මෙම සීමා කළ අවසරය නොමැතිව යෙදුම නිසි ලෙස ක්රියා නොකරනු ඇත. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ප්රවේශයට ඉඩ දෙන ආකාරය දැන ගන්න</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"යෙදුම පෙරනිමි <xliff:g id="ROLE_NAME">%1$s</xliff:g> වීමට ප්රවේශය ප්රතික්ෂේප කරන ලදි"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"යෙදුම ඔබේ පුද්ගලික සහ මූල්ය තොරතුරු අවදානමට ලක් කළ හැකි සංවේදී අවසර සඳහා ප්රවේශය ඉල්ලා ඇත.<xliff:g id="ID_1"><br><br></xliff:g>මෙම සීමා කළ අවසර නොමැතිව යෙදුම නිසි ලෙස ක්රියා නොකරනු ඇත. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ප්රවේශයට ඉඩ දෙන ආකාරය දැන ගන්න</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"යෙදුමට ප්රවේශය ප්රතික්ෂේප විය"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"මෙම අවසරයට ප්රවේශ වීම ඔබේ පුද්ගලික සහ මූල්ය තොරතුරු අවදානමට ලක් කළ හැක.<xliff:g id="ID_1"><br><br></xliff:g>මෙම සීමා කළ අවසරය නොමැතිව යෙදුම නිසි ලෙස ක්රියා නොකරනු ඇත. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ප්රවේශයට ඉඩ දෙන ආකාරය දැන ගන්න</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"තව දැන ගන්න"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"හරි"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"අවසර ඉල්ලීම වළක්වා ඇත"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"මෙම යෙදුම අතිරේක අවසර ඉල්ලා සිටින නමුත්, ප්රවාහ කිරීමේ සැසියක අවසර ලබා දිය නොහැක. පළමුව ඔබේ දුරකථනයෙන් අවසරය ලබා දෙන්න."</string> </resources> diff --git a/PermissionController/res/values-sk-v34/strings.xml b/PermissionController/res/values-sk-v34/strings.xml index 5f84f5059..e7212c8d5 100644 --- a/PermissionController/res/values-sk-v34/strings.xml +++ b/PermissionController/res/values-sk-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Správa prístupu aplikácie k údajom o zdraví"</string> <string name="location_settings" msgid="8863940440881290182">"Prístup k polohe"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Pre aplikácie a služby. Keď je toto nastavenie vypnuté a zavoláte na tiesňovú linku, údaje mikrofónu sa môžu stále zdieľať."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Pre aplikácie a služby"</string> </resources> diff --git a/PermissionController/res/values-sk-watch/strings.xml b/PermissionController/res/values-sk-watch/strings.xml index 8667362bb..1a7e89701 100644 --- a/PermissionController/res/values-sk-watch/strings.xml +++ b/PermissionController/res/values-sk-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Nedá sa zmeniť"</string> <string name="generic_yes" msgid="2489207724988649846">"Áno"</string> <string name="generic_cancel" msgid="2631708607129269698">"Zrušiť"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Po celý čas"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Pri používaní"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Po celý čas"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Pri používaní"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Po celý čas"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Pri používaní"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Po celý čas"</string> </resources> diff --git a/PermissionController/res/values-sk/strings.xml b/PermissionController/res/values-sk/strings.xml index 6680ddad9..c379461c2 100644 --- a/PermissionController/res/values-sk/strings.xml +++ b/PermissionController/res/values-sk/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Všetky povolenia"</string> <string name="other_permissions" msgid="2901186127193849594">"Ďalšie možnosti aplikácie"</string> <string name="permission_request_title" msgid="8790310151025020126">"Žiadosť o povolenie"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear nepodporuje akciu inštalácie/odinštalovania."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Vyberte, k čomu môže pristupovať aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> bola aktualizovaná. Vyberte, k čomu bude mať prístup."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Zrušiť"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Keď je presná poloha vypnutá, aplikácie majú prístup k vašej približnej polohe"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>: povolenie"</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: prístup tejto aplikácie"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Prístup k položke <xliff:g id="PERM">%1$s</xliff:g> pre túto aplikáciu v zariadení <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Zobraziť všetky povolenia aplikácie <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Zobraziť všetky aplikácie s týmto povolením"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Zobraziť používanie mikrofónu Asistentom"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Odstrániť povolenia, ak sa aplikácia nepoužíva"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Odstraňovať povol. a uvoľňovať priestor"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pozastaviť aktivitu v nepoužívaných apl."</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Spravovať aplikáciu, ak sa nepoužíva"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Odstrániť povolenia, vymazať dočasné súbory a zastaviť upozornenia"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Odstrániť povolenia, vymazať dočasné súbory, zastaviť upozornenia a archivovať aplikáciu"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Ak túto aplikáciu niekoľko mesiacov nepoužijete, v záujme ochrany vašich údajov budú odstránené jej povolenia."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Ak túto aplikáciu niekoľko mesiacov nepoužijete, v záujme ochrany vašich údajov budú odstránené tieto povolenia: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"V záujme ochrany vašich údajov boli odobrané povolenia aplikáciám, ktoré ste niekoľko mesiacov nepoužívali."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"S povolením spravovať všetky súbory"</string> <string name="ask_header" msgid="2633816846459944376">"Vždy sa opýtať"</string> <string name="denied_header" msgid="903209608358177654">"Nepovolené"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> v zariadení <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Zobraziť ďalšie aplikácie s prístupom k všetkým súborom"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 deň}few{# dni}many{# dňa}other{# dní}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# hodina}few{# hodiny}many{# hodiny}other{# hodín}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikácia na poznámky"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikácie, ktoré vám v zariadení umožňujú písať poznámky"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"poznámky"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Predvolená aplik. s peňaženkou"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikácia s peňaženkou"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplikácie s peňaženkou môžu uložiť vaše kreditné alebo vernostné karty, kľúče od auta a iné položky, aby vám mohli pomáhať s rôznymi druhmi transakcií."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Chcete nastaviť <xliff:g id="APP_NAME">%1$s</xliff:g> ako predvolenú aplikáciu s peňaženkou?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nie sú potrebné žiadne povolenia"</string> <string name="request_role_current_default" msgid="738722892438247184">"Aktuálne predvolená"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Nabudúce sa nepýtať"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Nastav. ako predvol."</string> @@ -512,7 +519,7 @@ <string name="permgroupupgraderequest_camera" msgid="640758449200241582">"Chcete aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> zmeniť prístup k fotoaparátu?"</string> <string name="permgroupupgraderequest_device_aware_camera" msgid="4198765626608612156">"Zmeniť prístup ku kamere pre <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> v zariadení <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgroupupgraderequestdetail_camera" msgid="6642747548010962597">"Táto aplikácia požaduje nepretržitý prístup k foteniu a nahrávaniu videí, aj keď ju nepoužívate. "<annotation id="link">"Povolíte ho v nastaveniach."</annotation></string> - <string name="permgrouprequest_calllog" msgid="2065327180175371397">"Chcete povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prístup k zoznamu tel. hovorov?"</string> + <string name="permgrouprequest_calllog" msgid="2065327180175371397">"Chcete povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> prístup k zoznamu hovorov?"</string> <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"Chcete aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> povoliť prístup k zoznamu hovorov telefónu v zariadení <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_phone" msgid="1829234136997316752">"Chcete povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uskutočňovať a spravovať telefonické hovory?"</string> <string name="permgrouprequest_device_aware_phone" msgid="4389610977195521813">"Povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uskutočňovať a spravovať telefonické hovor v zariadení <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Aktualizácie zdieľania údajov"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Niektoré aplikácie zmenili spôsob zdieľania údajov o polohe"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Nastavenia"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Otvorené <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Otvorené včera <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Otvorené <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Jednorazové heslo je 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Obmedzené nastavenie"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Z bezpečnostných dôvodov nie je toto nastavenie momentálne k dispozícii."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikácii bol prístup k povoleniu <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> zamietnutý"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Táto aplikácia vyžaduje prístup k citlivému povoleniu, čo môže ohroziť vaše osobné údaje a finančné informácie.<xliff:g id="ID_1"><br><br></xliff:g>Je možné, že bez tohto obmedzeného povolenia nebude aplikácia správne fungovať. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ako povoliť prístup</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikácii bol zamietnutý prístup a predvolene nemôže byť <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Táto aplikácia vyžaduje prístup k citlivým povoleniam, čo môže ohroziť vaše osobné údaje a finančné informácie.<xliff:g id="ID_1"><br><br></xliff:g>Je možné, že bez týchto obmedzených povolení nebude aplikácia správne fungovať. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ako povoliť prístup</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikácii bol zamietnutý prístup"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Prístup k tomuto povoleniu môže ohroziť vaše osobné údaje a finančné informácie.<xliff:g id="ID_1"><br><br></xliff:g>Je možné, že bez tohto obmedzeného povolenia nebude aplikácia správne fungovať. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Ako povoliť prístup</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Ďalšie informácie"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Žiadosť o povolenie bola zablokovaná"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Táto aplikácia požaduje ďalšie povolenia, ale povolenia nie je možné udeliť v relácii streamovania. Najprv udeľte povolenie v telefóne."</string> </resources> diff --git a/PermissionController/res/values-sl-v34/strings.xml b/PermissionController/res/values-sl-v34/strings.xml index 18afff3d1..11fafdf93 100644 --- a/PermissionController/res/values-sl-v34/strings.xml +++ b/PermissionController/res/values-sl-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Upravljajte dostop aplikacij do podatkov o zdravju."</string> <string name="location_settings" msgid="8863940440881290182">"Dostop do lokacije"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Za aplikacije in storitve. Če je ta nastavitev izklopljena, bodo podatki mikrofona morda še vedno deljeni, ko pokličete številko za klic v sili."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Za aplikacije in storitve."</string> </resources> diff --git a/PermissionController/res/values-sl-watch/strings.xml b/PermissionController/res/values-sl-watch/strings.xml index 83cff82ee..f93ba26b5 100644 --- a/PermissionController/res/values-sl-watch/strings.xml +++ b/PermissionController/res/values-sl-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Ni mogoče sprem."</string> <string name="generic_yes" msgid="2489207724988649846">"Da"</string> <string name="generic_cancel" msgid="2631708607129269698">"Prekliči"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Ves čas"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Med uporabo aplikacije"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Ves čas"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Med uporabo aplikacije"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Ves čas"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Med uporabo aplikacije"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Ves čas"</string> </resources> diff --git a/PermissionController/res/values-sl/strings.xml b/PermissionController/res/values-sl/strings.xml index d4b8a1037..b1bd39ae6 100644 --- a/PermissionController/res/values-sl/strings.xml +++ b/PermissionController/res/values-sl/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Vsa dovoljenja"</string> <string name="other_permissions" msgid="2901186127193849594">"Druge zmožnosti aplikacije"</string> <string name="permission_request_title" msgid="8790310151025020126">"Zahteva za dovoljenje"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Dejanja namestitve in odstranitve v sistemu Android Wear niso podprta."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Izberite, do česa aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dovolite dostop"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> je posodobljena. Izberite, do česa tej aplikaciji dovolite dostop."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Prekliči"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Ko je zaznavanje natančne lokacije izklopljeno, lahko aplikacije dostopajo do vaše približne lokacije."</string> <string name="app_permission_title" msgid="2090897901051370711">"Dovoljenje »<xliff:g id="PERM">%1$s</xliff:g>«"</string> <string name="app_permission_header" msgid="2951363137032603806">"Dostop te aplikacije do dovoljenja »<xliff:g id="PERM">%1$s</xliff:g>«"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Dostop do dovoljenja »<xliff:g id="PERM">%1$s</xliff:g>« za to aplikacijo v napravi <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Ogled vseh dovoljenj za aplikacijo <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Ogled vseh aplikacij s tem dovoljenjem"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Prikaz uporabe pomožnega mikrofona"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Odstrani dovoljenja, če aplikacija ni v uporabi"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Odstrani dovoljenja in sprosti prostor"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Zaustavi dejavnost aplikacije ob neuporabi"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Upravljanje aplikacije ob neuporabi"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Dovoljenja se odstranijo, začasne datoteke se izbrišejo in prikazovanje obvestil se ustavi."</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Odstranitev dovoljenj, izbris začasnih datotek, ustavitev prikazovanja obvestil in arhiviranje aplikacije"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Z namenom zaščite podatkov bodo dovoljenja za to aplikacijo odstranjena, če je več mesecev ne boste uporabljali."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Če aplikacije več mesecev ne boste uporabljali, bodo z namenom zaščite podatkov odstranjena ta dovoljenja: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Z namenom zaščite podatkov so bila odstranjena dovoljenja za aplikacije, ki jih več mesecev niste uporabljali."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Dovoljeno je upravljanje vseh datotek"</string> <string name="ask_header" msgid="2633816846459944376">"Vedno vprašaj"</string> <string name="denied_header" msgid="903209608358177654">"Ni dovoljeno"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"Skupina dovoljenj »<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>« v napravi <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Prikaži več aplikacij z dostopom do vseh datotek"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dan}one{# dan}two{# dneva}few{# dni}other{# dni}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ura}one{# ura}two{# uri}few{# ure}other{# ur}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikacija za zapiske"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikacije, ki vam omogočajo ustvarjanje zapiskov v napravi."</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"zapiski"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Privzeta aplikacija denarnice"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikacija denarnice"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"V aplikacijah denarnice lahko shranite kreditne kartice in kartice zvestobe, avtomobilske ključe ter druge stvari, ki vam omogočajo različne oblike transakcij."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Želite nastaviti <xliff:g id="APP_NAME">%1$s</xliff:g> kot privzeto aplikacijo denarnice?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nobeno dovoljenje ni potrebno"</string> <string name="request_role_current_default" msgid="738722892438247184">"Trenutna privzeta nastavitev"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ne vprašaj me več"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Nastavi kot privzeto"</string> @@ -524,7 +531,7 @@ <string name="permgroupbackgroundrequestdetail_sensors" msgid="7726767635834043501">"Če želite tej aplikaciji omogočiti stalen dostop do podatkov tipal telesnih funkcij, tudi ko je ne uporabljate, "<annotation id="link">"pojdite v nastavitve"</annotation>"."</string> <string name="permgroupupgraderequest_sensors" msgid="7576527638411370468">"Ali želite aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> še naprej dovoliti dostop do podatkov tipal telesnih funkcij, ko je v uporabi?"</string> <string name="permgroupupgraderequest_device_aware_sensors" msgid="3310667992344623159">"Žel. apl. <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> v napravi <b><xliff:g id="DEVICE">%2$s</xliff:g></b> še napr. dov. dost. do pod. tip. tel. funkc., ko je v upor.?"</string> - <string name="permgrouprequest_notifications" msgid="6396739062335106181">"Želite aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> omogočiti, da vam pošilja obvestila?"</string> + <string name="permgrouprequest_notifications" msgid="6396739062335106181">"Želite aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dovoliti, da vam pošilja obvestila?"</string> <string name="permgrouprequest_device_aware_notifications" msgid="7307588961166360244">"Želite aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dovoliti pošiljanje obvestil v napravi <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="auto_granted_permissions" msgid="6009452264824455892">"Zunanje upravljana dovoljenja"</string> <string name="auto_granted_location_permission_notification_title" msgid="7570818224669050377">"<xliff:g id="APP_NAME">%1$s</xliff:g> ima dostop do lokacije"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Posodobitve deljenja podatkov"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Nekatere aplikacije so spremenile način deljenja vaših lokacijskih podatkov."</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Nastavitve"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Zadnji dostop: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Zadnji dostop včeraj: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Zadnji dostop: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Enkratno geslo je 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Omejena nastavitev"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Zaradi vaše varnosti ta nastavitev trenutno ni na voljo."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikaciji je bil zavrnjen dostop do dovoljenja »<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>«"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikacija je zahtevala dostop do občutljivega dovoljenja, ki lahko ogrozi vaše osebne in finančne podatke.<xliff:g id="ID_1"><br><br></xliff:g>Aplikacija morda ne bo pravilno delovala brez tega omejenega dovoljenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Preberite, kako omogočite dostop</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikaciji je bil zavrnjen dostop do privzete vloge »<xliff:g id="ROLE_NAME">%1$s</xliff:g>«"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikacija je zahtevala dostop do občutljivih dovoljenj, ki lahko ogrozijo vaše osebne in finančne podatke.<xliff:g id="ID_1"><br><br></xliff:g>Aplikacija morda ne bo pravilno delovala brez teh omejenih dovoljenj. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Preberite, kako omogočite dostop</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikaciji je bil zavrnjen dostop"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Dostop do tega dovoljenja lahko ogrozi vaše osebne in finančne podatke.<xliff:g id="ID_1"><br><br></xliff:g>Aplikacija morda ne bo pravilno delovala brez tega omejenega dovoljenja. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Preberite, kako omogočite dostop</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Več o tem"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"V redu"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Zahteva za dovoljenje je bila prezrta"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ta aplikacija zahteva dodatna dovoljenja, vendar teh ni mogoče odobriti med sejo pretočnega predvajanja. Dovoljenje najprej odobrite v telefonu."</string> </resources> diff --git a/PermissionController/res/values-sq-v34/strings.xml b/PermissionController/res/values-sq-v34/strings.xml index bf9c922cd..960da8d7d 100644 --- a/PermissionController/res/values-sq-v34/strings.xml +++ b/PermissionController/res/values-sq-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Menaxho qasjen e aplikacioneve te të dhënat e shëndetit"</string> <string name="location_settings" msgid="8863940440881290182">"Qasja te vendndodhja"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Për aplikacionet dhe shërbimet. Nëse ky cilësim është joaktiv, të dhënat e mikrofonit mund të vazhdojnë të ndahen kur telefonon një numër urgjence."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Për aplikacionet dhe shërbimet"</string> </resources> diff --git a/PermissionController/res/values-sq-watch/strings.xml b/PermissionController/res/values-sq-watch/strings.xml index 3043bf520..cddff97c5 100644 --- a/PermissionController/res/values-sq-watch/strings.xml +++ b/PermissionController/res/values-sq-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Nuk mund të ndryshohet"</string> <string name="generic_yes" msgid="2489207724988649846">"Po"</string> <string name="generic_cancel" msgid="2631708607129269698">"Anulo"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Gjatë gjithë kohës"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Kur përdor aplikacionin"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Gjatë gjithë kohës"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Kur përdor aplikacionin"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Gjatë gjithë kohës"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Kur përdor aplikacionin"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Gjatë gjithë kohës"</string> </resources> diff --git a/PermissionController/res/values-sq/strings.xml b/PermissionController/res/values-sq/strings.xml index a32dfb4f7..f8819fcf6 100644 --- a/PermissionController/res/values-sq/strings.xml +++ b/PermissionController/res/values-sq/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Të gjitha lejet"</string> <string name="other_permissions" msgid="2901186127193849594">"Kapacitete të tjera të aplikacionit"</string> <string name="permission_request_title" msgid="8790310151025020126">"Kërkesa e lejes"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Instalo/çinstalo veprimet që nuk mbështeten në Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Zgjidh se ku do të lejohet të ketë qasje <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> është përditësuar. Zgjidh se ku do të lejohet të ketë qasje ky aplikacion."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Anulo"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kur është joaktive vendndodhja e saktë, aplikacionet mund të qasen te vendndodhja jote e përafërt"</string> <string name="app_permission_title" msgid="2090897901051370711">"Leje për te \"<xliff:g id="PERM">%1$s</xliff:g>\""</string> <string name="app_permission_header" msgid="2951363137032603806">"Qasja te \"<xliff:g id="PERM">%1$s</xliff:g>\" për këtë aplikacion"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Qasja te <xliff:g id="PERM">%1$s</xliff:g> për këtë aplikacion në <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Shiko të gjitha lejet e aplikacionit \"<xliff:g id="APP">%1$s</xliff:g>\""</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Shiko të gjitha aplikacionet me këtë leje"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Shfaq përdorimin e mikrofonit të \"Asistentit\""</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Hiq lejet nëse aplikacioni nuk është përdorur"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Hiq lejet dhe liro hapësirën"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Ndërprit aktivitetin nëse nuk përdoret"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Menaxho aplikacionin nëse nuk përdoret"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Hiq lejet, fshi skedarët e përkohshëm dhe ndalo njoftimet"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Hiq lejet, fshi skedarët e përkohshëm, ndalo njoftimet dhe arkivo aplikacionin"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Për të mbrojtur të dhënat e tua, lejet për këtë aplikacion do të hiqen nëse aplikacioni nuk përdoret për disa muaj."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Për të mbrojtur të dhënat e tua, nëse aplikacioni nuk është përdorur për disa muaj, lejet e mëposhtme do të hiqen: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Për të mbrojtur të dhënat e tua, lejet janë hequr nga aplikacionet që nuk i ke përdorur për disa muaj."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Lejohet të menaxhojë të gjithë skedarët"</string> <string name="ask_header" msgid="2633816846459944376">"Pyet çdo herë"</string> <string name="denied_header" msgid="903209608358177654">"Nuk lejohet"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> në <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Shiko më shumë aplikacione me qasje tek të gjithë skedarët"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ditë}other{# ditë}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# orë}other{# orë}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Aplikacioni për shënime"</string> <string name="role_notes_description" msgid="8496852798616883551">"Aplikacione që të lejojnë të mbash shënime në pajisjen tënde"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"shënime"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Aplikacioni i parazgjedhur i portofolit"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Aplikacioni i portofolit"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Aplikacionet e portofolit mund të ruajnë kartat e tua të kreditit dhe të besnikërisë, çelësat e makinës dhe gjëra të tjera për të të ndihmuar për forma të ndryshme transaksionesh."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Të caktohet <xliff:g id="APP_NAME">%1$s</xliff:g> si aplikacioni yt i parazgjedhur i portofolit?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Nuk nevojitet asnjë leje"</string> <string name="request_role_current_default" msgid="738722892438247184">"Parazgjedhja aktuale"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Mos pyet më"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Cakto si parazgjedhje"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Përditësimet për ndarjen e të dhënave"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Disa aplikacione ndryshuan mënyrën se si mund të ndajnë të dhënat e vendndodhjes sate"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Cilësimet"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Qasja e fundit në <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Qasja e fundit dje në <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Qasja e fundit më <xliff:g id="TIME_DATE_0">%1$s</xliff:g> në <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Fjalëkalimi yt njëpërdorimësh është 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Cilësim i kufizuar"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Për sigurinë tënde, ky cilësim nuk ofrohet për momentin."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikacionit iu refuzua qasja te: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikacioni kërkoi qasje në një leje delikate që mund t\'i vendosë në rrezik informacionet e tua personale dhe financiare.<xliff:g id="ID_1"><br><br></xliff:g>Ka mundësi që aplikacioni të mos funksionojë si duhet pa këtë leje të kufizuar. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Mëso se si të lejosh qasjen</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikacionit iu refuzua qasja për të qenë parazgjedhja për: <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Aplikacioni kërkoi qasje në leje delikate që mund t\'i vendosin në rrezik informacionet e tua personale dhe financiare.<xliff:g id="ID_1"><br><br></xliff:g>Ka mundësi që aplikacioni të mos funksionojë si duhet pa këto leje të kufizuara. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Mëso se si të lejosh qasjen</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Aplikacionit iu refuzua qasja"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Qasja në këtë leje mund t\'i vendosë në rrezik informacionet e tua personale dhe financiare.<xliff:g id="ID_1"><br><br></xliff:g>Ka mundësi që aplikacioni të mos funksionojë si duhet pa këtë leje të kufizuar. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Mëso se si të lejosh qasjen</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Mëso më shumë"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Në rregull"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Kërkesa për leje është ndaluar"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ky aplikacion po kërkon leje shtesë, por lejet nuk mund të jepen në një seancë transmetimi. Fillimisht jep lejen në telefonin tënd."</string> </resources> diff --git a/PermissionController/res/values-sr-v34/strings.xml b/PermissionController/res/values-sr-v34/strings.xml index 89233996c..3708c5d93 100644 --- a/PermissionController/res/values-sr-v34/strings.xml +++ b/PermissionController/res/values-sr-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Управљајте приступом апликација подацима о здрављу"</string> <string name="location_settings" msgid="8863940440881290182">"Приступ локацији"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"За апликације и услуге. Ако је ово подешавање искључено, подаци микрофона могу и даље да се деле када позовете број за хитне случајеве"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"За апликације и услуге"</string> </resources> diff --git a/PermissionController/res/values-sr-watch/strings.xml b/PermissionController/res/values-sr-watch/strings.xml index 6d9cff946..6f21adc03 100644 --- a/PermissionController/res/values-sr-watch/strings.xml +++ b/PermissionController/res/values-sr-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Не може да се промени"</string> <string name="generic_yes" msgid="2489207724988649846">"Да"</string> <string name="generic_cancel" msgid="2631708607129269698">"Откажи"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Све време"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"При коришћењу апликације"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Све време"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"При коришћењу апликације"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Све време"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"При коришћењу апликације"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Све време"</string> </resources> diff --git a/PermissionController/res/values-sr/strings.xml b/PermissionController/res/values-sr/strings.xml index 847f95fbb..9741dfb0b 100644 --- a/PermissionController/res/values-sr/strings.xml +++ b/PermissionController/res/values-sr/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Све дозволе"</string> <string name="other_permissions" msgid="2901186127193849594">"Остале могућности апликације"</string> <string name="permission_request_title" msgid="8790310151025020126">"Захтев за дозволу"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Радње Инсталирај/Деинсталирај нису подржане у Wear-у."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Изаберите чему <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> може да приступа"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Апликација <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> је ажурирана. Изаберите чему ова апликација може да приступа."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Откажи"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Апликације могу да приступају вашој приближној локацији када је прецизна искључена"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> - дозвола"</string> <string name="app_permission_header" msgid="2951363137032603806">"Приступ ове апликације функцији „<xliff:g id="PERM">%1$s</xliff:g>“"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Ова апликација има приступ за: <xliff:g id="PERM">%1$s</xliff:g> на уређају <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Прикажи све дозволе за: <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Прикажи све апликације са овом дозволом"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Прикажи како Помоћник користи микрофон"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Уклони дозволе ако се апликација не користи"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Уклони дозволе и ослободи простор"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Паузирај активности ако се не користи"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Управљајте апликацијом ако се не користи"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Уклоните дозволе, избришите привремене фајлове и зауставите обавештења"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Уклоните дозволе, избришите привремене фајлове, зауставите обавештења и архивирајте апликацију"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Ради заштите података, дозволе за ову апликацију се уклањају ако се апликација не користи пар месеци."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Ради заштите података, следеће дозволе се уклањају ако се апликација не користи пар месеци: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Ради заштите података, дозволе су уклоњене из апликација које нисте користили пар месеци."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Имају дозволу за управљање свим датотекама"</string> <string name="ask_header" msgid="2633816846459944376">"Питај сваки пут"</string> <string name="denied_header" msgid="903209608358177654">"Није дозвољено"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> на уређају <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Прикажи још апликација са приступом свим фајловима"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 дан}one{# дан}few{# дана}other{# дана}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# сат}one{# сат}few{# сата}other{# сати}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Апликација за белешке"</string> <string name="role_notes_description" msgid="8496852798616883551">"Апликације које вам омогућавају да правите белешке на уређају"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"белешке"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Подразумевана апликација Новчаник"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Апликација Новчаник"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Апликације Новчаник могу да чувају ваше кредитне картице и картице лојалности, кључеве од аутомобила и друге ствари како би вам помогли при различитим трансакцијама."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Желите да подесите <xliff:g id="APP_NAME">%1$s</xliff:g> као подразумевану апликацију Новчаник?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Није потребна ниједна дозвола"</string> <string name="request_role_current_default" msgid="738722892438247184">"Тренутно подразумевана"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Не питај поново"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Подеси као подразум."</string> @@ -438,7 +445,7 @@ <string name="no_special_app_access" msgid="6950277571805106247">"Нема посебног приступа апл."</string> <string name="special_app_access_no_apps" msgid="4102911722787886970">"Нема апликација"</string> <string name="home_missing_work_profile_support" msgid="1756855847669387977">"Не подржава пословни профил"</string> - <string name="encryption_unaware_confirmation_message" msgid="8274491794636402484">"Напомена: Ако рестартујете уређај и подесили сте закључавање екрана, ова апликација не може да се покрене док не откључате уређај."</string> + <string name="encryption_unaware_confirmation_message" msgid="8274491794636402484">"Напомена: Ако рестартујете уређај и подесили сте откључавање екрана, ова апликација не може да се покрене док не откључате уређај."</string> <string name="assistant_confirmation_message" msgid="7476540402884416212">"Помоћник ће моћи да чита информације о апликацијама које се користе у систему, укључујући информације видљиве на екрану или којима може да се приступа у оквиру апликација."</string> <string name="incident_report_channel_name" msgid="3144954065936288440">"Дељење података о отклањању грешака"</string> <string name="incident_report_notification_title" msgid="4635984625656519773">"Делите детаљне податке за отклањање грешака?"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"Ова апликација жели да снима звук све време, чак и када не користите апликацију. "<annotation id="link">"Дозволите у подешавањима."</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"Желите ли да дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> приступа физичким активностима?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"Дозвољавате да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> приступа подацима о физичким активностима на уређају <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"Желите да дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> снима слике и видео снимке?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"Желите да дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> снима слике и видео?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"Дозволићете да апликација <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> снима слике и видео снимке на уређају <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"Апликација ће моћи да снима слике и видео снимке само док користите апликацију"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"Желите да дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> снима слике и видео снимке?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Ажурирања за дељење података"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Неке апликације су промениле начин на који могу да деле податке о локацији"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Подешавања"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Приступано: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Приступано јуче: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Приступано: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Једнократна лозинка је 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Ограничено подешавање"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Ово подешавање је тренутно недоступно ради ваше безбедности."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Апликацији није дозвољен приступ дозволи: <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Апликација је затражила приступ осетљивој дозволи, што може да угрози безбедност личних и финансијских података.<xliff:g id="ID_1"><br><br></xliff:g>Апликација можда неће радити исправно без ове ограничене дозволе. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Сазнајте како да дозволите приступ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Апликацији није дозвољен приступ да постане подразумевана: <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Апликација је затражила приступ осетљивим дозволама, што може да угрози безбедност личних и финансијских података.<xliff:g id="ID_1"><br><br></xliff:g>Апликација можда неће радити исправно без ових ограничених дозвола. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Сазнајте како да дозволите приступ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Апликацији није дозвољен приступ"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Приступ овој дозволи може да угрози безбедност личних и финансијских података.<xliff:g id="ID_1"><br><br></xliff:g>Апликација можда неће радити исправно без ове ограничене дозволе. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Сазнајте како да дозволите приступ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Сазнајте више"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Важи"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Захтев за дозволу је блокиран"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ова апликација захтева додатне дозволе, али дозволе не могу да се дају у сесији стримовања. Прво дајте дозволу на телефону."</string> </resources> diff --git a/PermissionController/res/values-sv-v34/strings.xml b/PermissionController/res/values-sv-v34/strings.xml index 09e204e2e..f6e4f3571 100644 --- a/PermissionController/res/values-sv-v34/strings.xml +++ b/PermissionController/res/values-sv-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Hantera appars åtkomst till din hälsodata"</string> <string name="location_settings" msgid="8863940440881290182">"Platsåtkomst"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"För appar och tjänster. Om inställningen är inaktiverad kan mikrofondata fortfarande delas när du ringer ett nödnummer"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"För appar och tjänster"</string> </resources> diff --git a/PermissionController/res/values-sv-watch/strings.xml b/PermissionController/res/values-sv-watch/strings.xml index 0a170e27e..9086da508 100644 --- a/PermissionController/res/values-sv-watch/strings.xml +++ b/PermissionController/res/values-sv-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Kan inte ändras"</string> <string name="generic_yes" msgid="2489207724988649846">"Ja"</string> <string name="generic_cancel" msgid="2631708607129269698">"Avbryt"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Hela tiden"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"När appen används"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Hela tiden"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"När appen används"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Hela tiden"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"När appen används"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Hela tiden"</string> </resources> diff --git a/PermissionController/res/values-sv/strings.xml b/PermissionController/res/values-sv/strings.xml index 350d6528c..5898b325a 100644 --- a/PermissionController/res/values-sv/strings.xml +++ b/PermissionController/res/values-sv/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Alla behörigheter"</string> <string name="other_permissions" msgid="2901186127193849594">"Andra appbehörigheter"</string> <string name="permission_request_title" msgid="8790310151025020126">"Behörighetsbegäran"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Åtgärder för att installera/avinstallera stöds inte på Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Välj vad du vill ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> har uppdaterats. Välj vad du vill ge appen åtkomst till."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Avbryt"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"När exakt plats har inaktiverats har appar åtkomst till din ungefärliga plats"</string> <string name="app_permission_title" msgid="2090897901051370711">"Behörighet till <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Åtkomst till <xliff:g id="PERM">%1$s</xliff:g> för appen"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Åtkomst till <xliff:g id="PERM">%1$s</xliff:g> för den här appen på <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Visa alla behörigheter för <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Visa alla appar med den här behörigheten"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Visa mikrofonanvändning för assistenten"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Ta bort behörigheter om en app inte används"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Ta bort behörigheter och frigör utrymme"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausa appaktivitet om appen inte används"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Hantera appen om den inte används"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Ta bort behörigheter, radera tillfälliga filer och hindra aviseringar"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Ta bort behörigheter, radera tillfälliga filer, hindra aviseringar och arkivera appen"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Behörigheter tas bort av säkerhetsskäl från den här appen om den inte används på några månader."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Följande behörigheter tas bort av säkerhetsskäl från appen om den inte används på några månader: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Behörigheter har tagits bort av säkerhetsskäl från appar som inte har använts på några månader."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Tillåts att hantera alla filer"</string> <string name="ask_header" msgid="2633816846459944376">"Fråga varje gång"</string> <string name="denied_header" msgid="903209608358177654">"Tillåts inte"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> på <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Se fler appar som kan komma åt alla filer"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 dag}other{# dagar}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# timme}other{# timmar}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Anteckningsapp"</string> <string name="role_notes_description" msgid="8496852798616883551">"Appar som låter dig göra anteckningar på enheten"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"anteckningar"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Standardplånboksapp"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Plånboksapp"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Plånboksappar kan lagra dina kredit- och stamkundskort, bilnycklar och andra saker som hjälper till med olika sorters transaktioner."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Vill du ställa in <xliff:g id="APP_NAME">%1$s</xliff:g> som din standardplånboksapp?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Inga behörigheter krävs"</string> <string name="request_role_current_default" msgid="738722892438247184">"Nuvarande standardapp"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Fråga inte igen"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Ange som standard"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Vill du ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till dina kontakter?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Vill du ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till kontakter på <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"Vill du ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till enhetens plats?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Vill du ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till platsen för <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b>?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Vill du ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till platsen för din <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Appen får endast åtkomst till din plats när du använder den"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Vill du ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till enhetens plats?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Vill du ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till platsen för <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Uppdateringar av datadelning"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"En del appar har ändrat hur de kan dela din platsdata"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Inställningar"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Öppnades <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Öppnades i går <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Öppnades <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Ditt engångslösenord är 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Begränsad inställning"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Av säkerhetsskäl är den här inställningen inte tillgänglig för närvarande."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Appen nekades åtkomst till <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Appen begärde åtkomstbehörighet till känsliga uppgifter, vilket kan utsätta din personliga och finansiella information för risk.<xliff:g id="ID_1"><br><br></xliff:g>Appen kanske inte fungerar som den ska utan denna begränsade behörighet. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>&gtLäs mer om hur du tillåter åtkomst</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Appen nekades åtkomst till standardrollen för <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Appen begärde åtkomstbehörigheter till känsliga uppgifter, vilket kan utsätta din personliga och finansiella information för risk.<xliff:g id="ID_1"><br><br></xliff:g>Appen kanske inte fungerar som den ska utan dessa begränsade behörigheter. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>&gtLäs mer om hur du tillåter åtkomst</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Appen nekades åtkomst"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Åtkomst till denna behörighet kan utsätta din personliga och finansiella information för risk.<xliff:g id="ID_1"><br><br></xliff:g>Appen kanske inte fungerar som den ska utan denna begränsade behörighet. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>&gtLäs mer om hur du tillåter åtkomst</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Läs mer"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Begäran om behörighet har dolts"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Appen begär ytterligare behörigheter, men det går inte att bevilja behörigheter under streamingsessionen. Bevilja behörigheten på telefonen först."</string> </resources> diff --git a/PermissionController/res/values-sw-v34/strings.xml b/PermissionController/res/values-sw-v34/strings.xml index be6f2f72b..5e5d5f149 100644 --- a/PermissionController/res/values-sw-v34/strings.xml +++ b/PermissionController/res/values-sw-v34/strings.xml @@ -22,6 +22,5 @@ <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> <string name="health_connect_summary" msgid="815473513776882296">"Dhibiti uwezo wa programu wa kufikia data ya afya"</string> <string name="location_settings" msgid="8863940440881290182">"Uwezo wa kufikia mahali"</string> - <string name="mic_toggle_description" msgid="1504101620086616040">"Kwenye programu na huduma. Mipangilio hii ikizimwa, data ya maikrofoni bado inaweza ikashirikiwa unapopiga nambari ya dharura"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Kwenye programu na huduma"</string> + <string name="mic_toggle_description" msgid="1504101620086616040">"Kwenye programu na huduma. Mipangilio hii ikizimwa, data ya maikrofoni bado inaweza ikashirikiwa unapopiga namba ya dharura"</string> </resources> diff --git a/PermissionController/res/values-sw-watch/strings.xml b/PermissionController/res/values-sw-watch/strings.xml index b23b8b022..e6eb0999d 100644 --- a/PermissionController/res/values-sw-watch/strings.xml +++ b/PermissionController/res/values-sw-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Haiwezi kubadilishwa"</string> <string name="generic_yes" msgid="2489207724988649846">"Ndiyo"</string> <string name="generic_cancel" msgid="2631708607129269698">"Ghairi"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Muda wote"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Unapotumia programu"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Muda wote"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Unapotumia programu"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Muda wote"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Unapotumia programu"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Muda wote"</string> </resources> diff --git a/PermissionController/res/values-sw/strings.xml b/PermissionController/res/values-sw/strings.xml index 689ed6f9e..483b3d86e 100644 --- a/PermissionController/res/values-sw/strings.xml +++ b/PermissionController/res/values-sw/strings.xml @@ -67,7 +67,7 @@ <string name="review_permission_decisions" msgid="309559429150613632">"Uamuzi wa ruhusa wa hivi majuzi"</string> <string name="review_permission_decisions_view_all" msgid="90391040431566130">"Angalia uamuzi wa ruhusa zote za hivi majuzi"</string> <string name="review_permission_decisions_empty" msgid="8120775336417279806">"Hakuna uamuzi wa ruhusa wa hivi majuzi"</string> - <string name="auto_permission_manager_summary" msgid="9157438376234301354">"Dhibiti ufikiaji wa data kwenye kalenda, rekodi za nambari za simu na zaidi"</string> + <string name="auto_permission_manager_summary" msgid="9157438376234301354">"Dhibiti ufikiaji wa data kwenye kalenda, rekodi za namba za simu na zaidi"</string> <string name="granted_permission_decision" msgid="7824827491551861365">"Umeipa <xliff:g id="APP_NAME">%1$s</xliff:g> ruhusa ya kufikia <xliff:g id="PERMISSION_NAME">%2$s</xliff:g>"</string> <string name="denied_permission_decision" msgid="5308961501779563781">"Umeinyima <xliff:g id="APP_NAME">%1$s</xliff:g> ruhusa ya kufikia <xliff:g id="PERMISSION_NAME">%2$s</xliff:g>"</string> <string name="days_ago" msgid="6650359081551335629">"{count,plural, =0{Leo}=1{Siku moja iliyopita}other{Siku # zilizopita}}"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Ruhusa zote"</string> <string name="other_permissions" msgid="2901186127193849594">"Uwezo mwingine wa programu"</string> <string name="permission_request_title" msgid="8790310151025020126">"Ombi la idhini"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Huduma ya Android Wear haiwezi kutekeleza vitendo vya Kusakinisha au Kuondoa vipengee."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Chagua vipengee ambavyo unaruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifikie"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> imesasishwa. Chagua vipengee unavyoruhusu programu hii ifikie."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Ghairi"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Wakati umezima eneo mahususi, programu zinaweza kufikia eneo lako lililokadiriwa"</string> <string name="app_permission_title" msgid="2090897901051370711">"Ruhusa ya <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Idhini ya programu hii kufikia <xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Ufikaiji wa <xliff:g id="PERM">%1$s</xliff:g> katika programu hii kwenye <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Angalia ruhusa zote za <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Angalia programu zote zenye ruhusa hii"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Onyesha matumizi ya maikrofoni ya mratibu"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Ondoa ruhusa ikiwa programu haitumiki"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Ondoa ruhusa na upate nafasi"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Simamisha shughuli kwenye programu ikiwa haitumiki"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Dhibiti programu iwapo haitumiki"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Ondoa ruhusa, futa faili za muda na usitishe arifa"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Ondoa ruhusa, futa faili za muda, komesha arifa na uweke programu kwenye kumbukumbu"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Ili kulinda data yako, ruhusa za programu hii zitaondolewa programu isipotumika kwa miezi michache."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Ili kulinda data yako, programu isipotumika kwa miezi michache, ruhusa zifuatazo zitaondolewa: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Ili kulinda data yako, ruhusa zimeondolewa kwenye programu ambazo hujatumia kwa miezi michache."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Zinazoruhusiwa kudhibiti faili zote"</string> <string name="ask_header" msgid="2633816846459944376">"Uliza kila wakati"</string> <string name="denied_header" msgid="903209608358177654">"Zisizoruhusiwa"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> kwenye <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Angalia programu zaidi zinazoweza kufikia faili zote"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{Siku moja}other{Siku #}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{Saa #}other{Saa #}}"</string> @@ -365,7 +367,7 @@ <string name="role_dialer_search_keywords" msgid="3324448983559188087">"kipiga simu"</string> <string name="role_sms_label" msgid="8456999857547686640">"Programu chaguomsingi ya SMS"</string> <string name="role_sms_short_label" msgid="4371444488034692243">"Programu ya SMS"</string> - <string name="role_sms_description" msgid="3424020199148153513">"Programu zinazokuruhusu kutumia nambari yako ya simu kutuma na kupokea ujumbe mfupi, picha, video na zaidi"</string> + <string name="role_sms_description" msgid="3424020199148153513">"Programu zinazokuruhusu kutumia namba yako ya simu kutuma na kupokea ujumbe mfupi, picha, video na zaidi"</string> <string name="role_sms_request_title" msgid="7953552109601185602">"Ungependa kuweka <xliff:g id="APP_NAME">%1$s</xliff:g> iwe programu yako chaguomsingi ya SMS?"</string> <string name="role_sms_request_description" msgid="2691004766132144886">"Programu hii itapewa uwezo wa kufikia Kamera, Anwani, Faili na maudhui, Maikrofoni, Simu na SMS kwenye kifaa chako"</string> <string name="role_sms_search_keywords" msgid="8022048144395047352">"SMS, kutuma SMS, ujumbe, kutuma ujumbe"</string> @@ -383,12 +385,12 @@ <string name="role_home_search_keywords" msgid="3830755001192666285">"kifungua programu"</string> <string name="role_call_redirection_label" msgid="5785304207206147590">"Programu chaguomsingi ya kuelekeza simu kwingine"</string> <string name="role_call_redirection_short_label" msgid="7568143419571217757">"Programu ya kuelekeza simu"</string> - <string name="role_call_redirection_description" msgid="6091669882014664420">"Programu zinazokuruhusu usambaze simu unazopiga kwenye nambari nyingine ya simu"</string> + <string name="role_call_redirection_description" msgid="6091669882014664420">"Programu zinazokuruhusu usambaze simu unazopiga kwenye namba nyingine ya simu"</string> <string name="role_call_redirection_request_title" msgid="2816244455003562925">"Je, ungependa kuweka <xliff:g id="APP_NAME">%1$s</xliff:g> iwe programu yako chaguomsingi ya kuelekeza simu kwingine?"</string> <string name="role_call_redirection_request_description" msgid="3118895714178527164">"Hakuna ruhusa zinazohitajika"</string> <string name="role_call_screening_label" msgid="883935222060878724">"Kutambua taka na anayepiga: programu msingi"</string> <string name="role_call_screening_short_label" msgid="2048465565063130834">"Kutambua anayepiga na taka"</string> - <string name="role_call_screening_description" msgid="2349431420497468981">"Programu zinazokuruhusu utambue simu zinazoingia na kuzuia taka, simu zinazopigwa kiotomatiki au nambari zisizohitajika"</string> + <string name="role_call_screening_description" msgid="2349431420497468981">"Programu zinazokuruhusu utambue simu zinazoingia na kuzuia taka, simu zinazopigwa kiotomatiki au namba zisizohitajika"</string> <string name="role_call_screening_request_title" msgid="7358309224566977290">"Je, ungependa kuweka <xliff:g id="APP_NAME">%1$s</xliff:g> iwe programu chaguomsingi ya kukagua kitambulisho cha anayepiga na taka?"</string> <string name="role_call_screening_request_description" msgid="7338511921032446006">"Hakuna ruhusa zinazohitajika"</string> <string name="role_automotive_navigation_label" msgid="2701890757955474751">"Programu chaguomsingi ya maelekezo"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Programu ya madokezo"</string> <string name="role_notes_description" msgid="8496852798616883551">"Programu zinazokuruhusu uandike madokezo kwenye kifaa chako"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"madokezo"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Programu chaguomsingi ya pochi"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Programu ya pochi"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Unaweza kuhifadhi kadi zako za mikopo na za kutuza uaminifu, funguo za magari na mengine kwenye programu za Pochi ili kukusaidia kufanya miamala mbalimbali."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Ungependa kuweka <xliff:g id="APP_NAME">%1$s</xliff:g> iwe programu yako chaguomsingi ya pochi?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Hakuna ruhusa zinazohitajika"</string> <string name="request_role_current_default" msgid="738722892438247184">"Chaguomsingi ya sasa"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Isiniulize tena"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Weka iwe chaguomsingi"</string> @@ -512,8 +519,8 @@ <string name="permgroupupgraderequest_camera" msgid="640758449200241582">"Ungependa kubadilisha ruhusa za <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> za kufikia kamera?"</string> <string name="permgroupupgraderequest_device_aware_camera" msgid="4198765626608612156">"Ungependa kubadilisha idhini ya kufikia ya kamera ya <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> kwenye <b><xliff:g id="DEVICE">%2$s</xliff:g></b> yako?"</string> <string name="permgroupupgraderequestdetail_camera" msgid="6642747548010962597">"Programu hii inataka kupiga picha na kurekodi video kila wakati, hata wakati huitumii."<annotation id="link">"Ruhusu katika mipangilio."</annotation></string> - <string name="permgrouprequest_calllog" msgid="2065327180175371397">"Ungependa kuiruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifikie rekodi zako za nambari za simu?"</string> - <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"Ungependa kuiruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifikie rekodi za nambari za simu yako kwenye <b><xliff:g id="DEVICE">%2$s</xliff:g></b> yako?"</string> + <string name="permgrouprequest_calllog" msgid="2065327180175371397">"Ungependa kuiruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifikie rekodi zako za namba za simu?"</string> + <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"Ungependa kuiruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifikie rekodi za namba za simu yako kwenye <b><xliff:g id="DEVICE">%2$s</xliff:g></b> yako?"</string> <string name="permgrouprequest_phone" msgid="1829234136997316752">"Ungependa kuruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> kupiga na kudhibiti simu?"</string> <string name="permgrouprequest_device_aware_phone" msgid="4389610977195521813">"Ungependa kuiruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ipige na kudhibiti simu kwenye <b><xliff:g id="DEVICE">%2$s</xliff:g></b> yako?"</string> <string name="permgrouprequest_sensors" msgid="4397358316850652235">"Ungependa kuiruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifikie data ya vitambuzi kuhusu viashiria muhimu vya mwili wako?"</string> @@ -547,7 +554,7 @@ <string name="blocked_microphone_title" msgid="1631517143648232585">"Maikrofoni ya kifaa imezuiwa"</string> <string name="blocked_location_title" msgid="2005608279812892383">"Utambuzi wa mahali kifaa kilipo umezimwa"</string> <string name="blocked_sensor_summary" msgid="4443707628305027375">"Kwa ajili ya programu na huduma"</string> - <string name="blocked_mic_summary" msgid="8960466941528458347">"Huenda bado data ya maikrofoni ikashirikiwa unapopigia nambari ya dharura."</string> + <string name="blocked_mic_summary" msgid="8960466941528458347">"Huenda bado data ya maikrofoni ikashirikiwa unapopigia namba ya dharura."</string> <string name="blocked_sensor_button_label" msgid="6742092634984289658">"Badilisha"</string> <string name="safety_center_dashboard_page_title" msgid="2810774008694315854">"Usalama na faragha"</string> <string name="safety_center_rescan_button" msgid="4517514567809409596">"Kagua kifaa"</string> @@ -609,7 +616,7 @@ <string name="camera_toggle_title" msgid="1251201397431837666">"Ufikiaji wa kamera"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"Ufikiaji wa maikrofoni"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Kwenye programu na huduma"</string> - <string name="mic_toggle_description" msgid="9163104307990677157">"Kwenye programu na huduma. Mipangilio hii ikizimwa, huenda data ya maikrofoni ikaendelea kushirikiwa unapopiga nambari ya dharura."</string> + <string name="mic_toggle_description" msgid="9163104307990677157">"Kwenye programu na huduma. Mipangilio hii ikizimwa, huenda data ya maikrofoni ikaendelea kushirikiwa unapopiga namba ya dharura."</string> <string name="location_settings_subtitle" msgid="2328360561197430695">"Angalia huduma na programu zenye uwezo wa kufikia mipangilio ya mahali"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Onyesha ufikiaji wa ubao wa kunakili"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"Onyesha ujumbe programu zinapofikia maandishi, picha au maudhui mengine uliyonakili"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Masasisho ya kushiriki data"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Baadhi ya programu zimebadilisha jinsi zinavyoweza kushiriki data ya mahali ulipo"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Mipangilio"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Kilifunguliwa <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Kilifunguliwa jana <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Kilifunguliwa <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Nenosiri lako la wakati mmoja ni 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Mipangilio imezuiwa"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Ili kulinda usalama wako, mipangilio hii haipatikani kwa sasa."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Programu haijapewa idhini ya kufikia <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Programu imeomba kufikia ruhusa nyeti, hali ambayo inaweza kuhatarisha maelezo yako ya kifedha na ya binafsi.<xliff:g id="ID_1"><br><br></xliff:g>Kuna uwezekano kuwa programu haitafanya kazi vizuri bila ruhusa hii inayodhibitiwa. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Pata maelezo kuhusu jinsi ya kuruhusu ufikiaji</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Programu haijapewa idhini ya kuwa <xliff:g id="ROLE_NAME">%1$s</xliff:g> chaguomsingi"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Programu imeomba kufikia ruhusa nyeti, hali ambayo inaweza kuhatarisha maelezo yako ya kifedha na ya binafsi.<xliff:g id="ID_1"><br><br></xliff:g>Kuna uwezekano kuwa programu haitafanya kazi vizuri bila ruhusa hii inayodhibitiwa. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Pata maelezo kuhusu jinsi ya kuruhusu ufikiaji</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Programu haijapewa idhini"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Ufikiaji wa ruhusa hii unaweza kuhatarisha maelezo yako ya kifedha na ya binafsi.<xliff:g id="ID_1"><br><br></xliff:g>Kuna uwezekano kuwa programu haitafanya kazi vizuri bila ruhusa hii inayodhibitiwa. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Pata maelezo kuhusu jinsi ya kuruhusu ufikiaji</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Pata maelezo zaidi"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Sawa"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Ombi la ruhusa limezuiwa"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Programu hii inaomba ruhusa za ziada. Hata hivyo, huwezi kutoa ruhusa ukitiririsha. Ruhusu kwenye simu yako kwanza."</string> </resources> diff --git a/PermissionController/res/values-ta-v34/strings.xml b/PermissionController/res/values-ta-v34/strings.xml index b92b9a184..593225811 100644 --- a/PermissionController/res/values-ta-v34/strings.xml +++ b/PermissionController/res/values-ta-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"உடல் ஆரோக்கியத் தரவுக்கான ஆப்ஸ் அணுகலை நிர்வகிக்கலாம்"</string> <string name="location_settings" msgid="8863940440881290182">"இருப்பிட அணுகல்"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ஆப்ஸ் மற்றும் சேவைகளுக்கு. இந்த அமைப்பு முடக்கப்பட்டிருந்தாலும் அவசர உதவி எண்ணை நீங்கள் அழைக்கும்போது மைக்ரோஃபோன் தரவு பகிரப்படலாம்"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ஆப்ஸ் & சேவைகளுக்கு"</string> </resources> diff --git a/PermissionController/res/values-ta-watch/strings.xml b/PermissionController/res/values-ta-watch/strings.xml index 8ba5ec786..51073c144 100644 --- a/PermissionController/res/values-ta-watch/strings.xml +++ b/PermissionController/res/values-ta-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"மாற்ற இயலாது"</string> <string name="generic_yes" msgid="2489207724988649846">"சரி"</string> <string name="generic_cancel" msgid="2631708607129269698">"வேண்டாம்"</string> + <string name="permission_access_always" msgid="2107115233573823032">"எப்போதும்"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ஆப்ஸைப் பயன்படுத்தும்போது"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"எப்போதும்"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ஆப்ஸைப் பயன்படுத்தும்போது"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"எப்போதும்"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ஆப்ஸைப் பயன்படுத்தும்போது"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"எப்போதும்"</string> </resources> diff --git a/PermissionController/res/values-ta/strings.xml b/PermissionController/res/values-ta/strings.xml index 70d71f31b..952862480 100644 --- a/PermissionController/res/values-ta/strings.xml +++ b/PermissionController/res/values-ta/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"அனைத்து அனுமதிகளும்"</string> <string name="other_permissions" msgid="2901186127193849594">"ஆப்ஸிற்கான பிற அனுமதிகள்"</string> <string name="permission_request_title" msgid="8790310151025020126">"அனுமதி கோரிக்கை"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"நிறுவல்/நிறுவல் நீக்குதலை Wearரில் செய்ய இயலாது."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> எவற்றையெல்லாம் அணுகலாம் என்பதைத் தேர்வுசெய்யவும்"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> புதுப்பிக்கப்பட்டது. இந்த ஆப்ஸ் எவற்றையெல்லாம் அணுகலாம் என்பதைத் தேர்வுசெய்யவும்."</string> <string name="review_button_cancel" msgid="2191147944056548886">"வேண்டாம்"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"துல்லியமான இருப்பிடம் ஆஃப் செய்யப்பட்டிருக்கும்போது உங்கள் தோராயமான இருப்பிடத்தை ஆப்ஸ் அணுகலாம்"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> என்பதற்கான அனுமதி"</string> <string name="app_permission_header" msgid="2951363137032603806">"இந்த ஆப்ஸிற்கு <xliff:g id="PERM">%1$s</xliff:g> அணுகல்"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> சாதனத்தில் இந்த ஆப்ஸுக்கான <xliff:g id="PERM">%1$s</xliff:g> அணுகல்"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"அனைத்து <xliff:g id="APP">%1$s</xliff:g> அனுமதிகளையும் காட்டு"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"இந்த அனுமதியைக் கொண்டுள்ள அனைத்து ஆப்ஸையும் காட்டு"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"அசிஸ்டண்ட் மைக்ரோஃபோன் உபயோகத்தைக் காட்டு"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"இந்த ஆப்ஸ் பயன்படுத்தப்படவில்லை என்றால் அனுமதிகளை அகற்றவும்"</string> <string name="unused_apps_label" msgid="2595428768404901064">"அனுமதிகளை அகற்றி இடத்தைக் காலியாக்கு"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"செயலில் இல்லாதபோது ஆப்ஸை இடைநிறுத்துதல்"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"ஆப்ஸைப் பயன்படுத்தாதபோது நிர்வகித்தல்"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"அனுமதிகளை அகற்றும், தற்காலிக ஃபைல்களை நீக்கும், அறிவிப்புகளை நிறுத்தும்"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"அனுமதிகளை அகற்றும், தற்காலிக ஃபைல்களை நீக்கும், அறிவிப்புகளை நிறுத்தும், ஆப்ஸைக் காப்பிடும்"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"இந்த ஆப்ஸைச் சில மாதங்கள் பயன்படுத்தவில்லை என்றால் உங்கள் தரவைப் பாதுகாப்பதற்காக இதற்கான அனுமதிகள் அகற்றப்படும்."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"இந்த ஆப்ஸைச் சில மாதங்கள் பயன்படுத்தவில்லை என்றால் உங்கள் தரவைப் பாதுகாப்பதற்காக பின்வரும் அனுமதிகள் அகற்றப்படும்: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"உங்கள் தரவைப் பாதுகாப்பதற்காக, கடந்த சில மாதங்களில் நீங்கள் பயன்படுத்தாத ஆப்ஸில் இருந்து அனுமதிகள் அகற்றப்பட்டன."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"எல்லா ஃபைல்களையும் நிர்வகிக்கும் அணுகலுள்ளவை"</string> <string name="ask_header" msgid="2633816846459944376">"ஒவ்வொரு முறையும் கேள்"</string> <string name="denied_header" msgid="903209608358177654">"அனுமதிக்கப்படாதவை"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> சாதனத்தில் <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"அனைத்து ஃபைல்களையும் அணுகக்கூடிய கூடுதல் ஆப்ஸைப் பாருங்கள்"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 நாள்}other{# நாட்கள்}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# மணிநேரம்}other{# மணிநேரம்}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"குறிப்பு எடுப்பதற்கான ஆப்ஸ்"</string> <string name="role_notes_description" msgid="8496852798616883551">"உங்கள் சாதனத்தில் குறிப்புகள் எடுக்க அனுமதிக்கும் ஆப்ஸ்"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"குறிப்புகள்"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"இயல்புநிலை வாலட் ஆப்ஸ்"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"வாலட் ஆப்ஸ்"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"பல்வேறு வகையான பரிமாற்றங்கள் தொடர்பாக உங்களுக்கு உதவ கிரெடிட் கார்டுகள், லாயல்டி கார்டுகள், கார் சாவிகள் மற்றும் பிறவற்றை வாலட் ஆப்ஸில் சேமிக்கலாம்."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸை உங்கள் இயல்புநிலை வாலட் ஆப்ஸாக அமைக்கவா?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"அனுமதிகள் தேவையில்லை"</string> <string name="request_role_current_default" msgid="738722892438247184">"தற்போதைய இயல்பான ஆப்ஸ்"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"மீண்டும் கேட்காதே"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"இயல்பு ஆப்ஸாக அமை"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"தரவுப் பகிர்வு குறித்த அறிவிப்புகள்"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"உங்கள் இருப்பிடத் தரவைப் பகிரும் விதத்தைச் சில ஆப்ஸ் மாற்றியுள்ளன"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"அமைப்புகள்"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"அணுகிய நேரம்: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"நேற்று அணுகிய நேரம்: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"அணுகிய நேரம்: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"ஒருமுறை பயன்படுத்தப்படும் கடவுச்சொல்: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"கட்டுப்படுத்தப்பட்ட அமைப்பு"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"உங்கள் பாதுகாப்பிற்காக, இந்த அமைப்பு தற்போது இல்லை."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>க்கான ஆப்ஸ் அணுகல் நிராகரிக்கப்பட்டது"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"பாதுகாக்க வேண்டிய தகவல்களுக்கான அனுமதியை வழங்க ஆப்ஸ் கேட்டுள்ளது, இது உங்கள் தனிப்பட்ட மற்றும் நிதித் தகவல்களை ஆபத்துக்குள்ளாக்கலாம்.<xliff:g id="ID_1"><br><br></xliff:g>இந்தக் கட்டுப்படுத்தப்பட்ட அனுமதி இல்லாமல் ஆப்ஸ் சரியாக வேலை செய்யாமல் போகக்கூடும். <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>எப்படி அணுகல் வழங்குவதென அறிக</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"இயல்புநிலை <xliff:g id="ROLE_NAME">%1$s</xliff:g>க்கான ஆப்ஸ் அணுகல் நிராகரிக்கப்பட்டது"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"பாதுகாக்க வேண்டிய தகவல்களுக்கான அனுமதிகளை வழங்க ஆப்ஸ் கேட்டுள்ளது, இது உங்கள் தனிப்பட்ட மற்றும் நிதித் தகவல்களை ஆபத்துக்குள்ளாக்கலாம்.<xliff:g id="ID_1"><br><br></xliff:g>இந்தக் கட்டுப்படுத்தப்பட்ட அனுமதிகள் இல்லாமல் ஆப்ஸ் சரியாக வேலை செய்யாமல் போகக்கூடும். <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>எப்படி அணுகல் வழங்குவதென அறிக</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ஆப்ஸ் அணுகல் நிராகரிக்கப்பட்டது"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"இதற்கு அனுமதி அளிப்பதனால் உங்கள் தனிப்பட்ட மற்றும் நிதித் தகவல்கள் ஆபத்துக்குள்ளாகலாம்.<xliff:g id="ID_1"><br><br></xliff:g>இந்தக் கட்டுப்படுத்தப்பட்ட அனுமதி இல்லாமல் ஆப்ஸ் சரியாக வேலை செய்யாமல் போகக்கூடும். <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>எப்படி அணுகல் வழங்குவதென அறிக</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"மேலும் அறிக"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"சரி"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"அணுகல் கோரிக்கை முடக்கப்பட்டது"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"இந்த ஆப்ஸ் கூடுதல் அனுமதிகளைக் கேட்கிறது. ஆனால் ஸ்ட்ரீமிங் அமர்வில் அனுமதிகள் வழங்கப்படாது. முதலில் உங்கள் மொபைலில் அனுமதி வழங்கவும்."</string> </resources> diff --git a/PermissionController/res/values-te-v34/strings.xml b/PermissionController/res/values-te-v34/strings.xml index c8281ea1d..f3df7f7d3 100644 --- a/PermissionController/res/values-te-v34/strings.xml +++ b/PermissionController/res/values-te-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"ఆరోగ్యానికి సంబంధించిన డేటాకు యాప్ యాక్సెస్ను మేనేజ్ చేయండి"</string> <string name="location_settings" msgid="8863940440881290182">"లొకేషన్ యాక్సెస్"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"యాప్లు, సర్వీస్ల కోసం. ఈ సెట్టింగ్ ఆఫ్ చేసి ఉన్నా కూడా, మీరు ఎమర్జెన్సీ నంబర్కు కాల్ చేసినప్పుడు మైక్రోఫోన్ డేటా షేర్ చేయబడవచ్చు"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"యాప్లు, సర్వీస్ల కోసం"</string> </resources> diff --git a/PermissionController/res/values-te-watch/strings.xml b/PermissionController/res/values-te-watch/strings.xml index dfd5af38f..57f32b8d3 100644 --- a/PermissionController/res/values-te-watch/strings.xml +++ b/PermissionController/res/values-te-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"మార్చడం సాధ్యపడదు"</string> <string name="generic_yes" msgid="2489207724988649846">"అవును"</string> <string name="generic_cancel" msgid="2631708607129269698">"రద్దు చేయండి"</string> + <string name="permission_access_always" msgid="2107115233573823032">"అన్ని సమయాలలో అనుమతించండి"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"యాప్ను వాడుతున్నప్పుడు"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"అన్ని సమయాలలో అనుమతించండి"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"యాప్ను వాడుతున్నప్పుడు"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"అన్ని సమయాలలో అనుమతించండి"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"యాప్ను వాడుతున్నప్పుడు"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"అన్ని సమయాలలో అనుమతించండి"</string> </resources> diff --git a/PermissionController/res/values-te/strings.xml b/PermissionController/res/values-te/strings.xml index 22eae448d..3ebb3941d 100644 --- a/PermissionController/res/values-te/strings.xml +++ b/PermissionController/res/values-te/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"అన్ని అనుమతులు"</string> <string name="other_permissions" msgid="2901186127193849594">"ఇతర యాప్ సామర్థ్యాలు"</string> <string name="permission_request_title" msgid="8790310151025020126">"అనుమతి రిక్వెస్ట్"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android వేర్"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wearలో ఇన్స్టాల్/అన్ఇన్స్టాల్ చర్యలకు మద్దతు లేదు."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> యాక్సెస్ చేయడానికి అనుమతించాల్సిన వాటిని ఎంచుకోండి"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> అప్డేట్ చేయబడింది. ఈ యాప్ యాక్సెస్ చేయడానికి అనుమతించాల్సిన వాటిని ఎంచుకోండి."</string> <string name="review_button_cancel" msgid="2191147944056548886">"రద్దు చేయండి"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"ఖచ్చితమైన లొకేషన్ అనే సెట్టింగ్ ఆఫ్లో ఉన్నప్పుడు, యాప్లు మీ సుమారు లొకేషన్ను యాక్సెస్ చేయగలవు"</string> <string name="app_permission_title" msgid="2090897901051370711">"\'<xliff:g id="PERM">%1$s</xliff:g>\' అనుమతి"</string> <string name="app_permission_header" msgid="2951363137032603806">"ఈ యాప్ కోసం \'<xliff:g id="PERM">%1$s</xliff:g>\' యాక్సెస్ను ఇవ్వాలా? వద్దా"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> పరికరంలో ఈ యాప్నకు <xliff:g id="PERM">%1$s</xliff:g> యాక్సెస్"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"అన్ని \'<xliff:g id="APP">%1$s</xliff:g>\' అనుమతులను చూడండి"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ఈ అనుమతి ఉన్న అన్ని యాప్లను చూడండి"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"అసిస్టెంట్ మైక్రోఫోన్ వినియోగాన్ని చూపు"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"యాప్ని ఉపయోగించకపోతే, అనుమతులను తీసివేయండి"</string> <string name="unused_apps_label" msgid="2595428768404901064">"అనుమతులను తీసివేసి స్పేస్ను ఖాళీ చేయండి"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"యాప్ను ఉపయోగించకపోతే దాని యాక్టివిటీని పాజ్ చేయండి"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"యాప్ను ఉపయోగించకపోతే, మేనేజ్ చేయండి"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"అనుమతులను తీసివేయండి, తాత్కాలిక ఫైళ్లను తొలగించండి, అలాగే నోటిఫికేషన్లను ఆపివేయండి"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"అనుమతులను తీసివేయండి, తాత్కాలిక ఫైళ్లను తొలగించండి, నోటిఫికేషన్లను ఆపివేయండి, యాప్ను ఆర్కైవ్ చేయండి"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"మీ డేటాను సురక్షితంగా ఉంచడానికి, ఈ యాప్ కొన్ని నెలలుగా వినియోగంలో లేకుంటే, దాని అనుమతులు తీసివేయబడతాయి."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"మీ డేటాను సురక్షితంగా ఉంచడానికి, ఈ యాప్ కొన్ని నెలలుగా వినియోగంలో లేకుంటే, దానికి ఇచ్చిన కింది అనుమతులు తీసివేయబడతాయి: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"మీ డేటాను సురక్షితంగా ఉంచడానికి, కొన్ని నెలలుగా వినియోగంలో లేని యాప్ల అనుమతులు తీసివేయబడ్డాయి."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ఫైల్స్ అన్నింటినీ మేనేజ్ చేసేందుకు అనుమతించబడినవి"</string> <string name="ask_header" msgid="2633816846459944376">"ప్రతిసారి అడగాలి"</string> <string name="denied_header" msgid="903209608358177654">"అనుమతించబడలేదు"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>లో <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"అన్ని ఫైళ్లను యాక్సెస్ చేయగల మరిన్ని యాప్లను చూడండి"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 రోజు}other{# రోజులు}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# గంట}other{# గంటలు}}"</string> @@ -268,7 +270,7 @@ <string name="unused_apps_notification_title" msgid="4314832015894238019">"{count,plural, =1{# ఉపయోగించని యాప్}other{# ఉపయోగించని యాప్లు}}"</string> <string name="unused_apps_notification_content" msgid="9195026773244581246">"అనుమతులు, తాత్కాలిక ఫైళ్లు తీసివేయబడ్డాయి అలాగే నోటిఫికేషన్లు ఆపివేయబడ్డాయి. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string> <string name="unused_apps_safety_center_card_title" msgid="5638409355530099149">"అనుమతులు తీసివేయబడిన యాప్లను రివ్యూ చేయండి"</string> - <string name="unused_apps_safety_center_card_content" msgid="1088557243627427820">"కొంతకాలంగా మీరు ఉపయోగించని యాప్లకు సంబంధించిన అనుమతులు, తాత్కాలిక ఫైల్లు తొలగించబడ్డాయి, అలాగే నోటిఫికేషన్లు నిలిపివేయబడ్డాయి."</string> + <string name="unused_apps_safety_center_card_content" msgid="1088557243627427820">"కొంతకాలంగా మీరు ఉపయోగించని యాప్లకు సంబంధించిన అనుమతులు, తాత్కాలిక ఫైళ్లు తొలగించబడ్డాయి, అలాగే నోటిఫికేషన్లు నిలిపివేయబడ్డాయి."</string> <string name="unused_apps_safety_center_action_title" msgid="8865914432518993194">"యాప్లను రివ్యూ చేయండి"</string> <string name="post_drive_permission_decision_reminder_title" msgid="1290697371418139976">"ఇటీవలి అనుమతులను చెక్ చేయండి"</string> <string name="post_drive_permission_decision_reminder_summary_1_app_1_permission" msgid="670521503734140711">"డ్రైవింగ్లో ఉన్నప్పుడు, మీరు <xliff:g id="APP">%1$s</xliff:g> యాప్నకు <xliff:g id="PERMISSION">%2$s</xliff:g>కు యాక్సెస్ను ఇచ్చారు"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"నోట్స్ యాప్"</string> <string name="role_notes_description" msgid="8496852798616883551">"మీ పరికరంలో నోట్స్ తీసుకోవడానికి మిమ్మల్ని అనుమతించే యాప్లు"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"నోట్స్"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"డిఫాల్ట్ వాలెట్ యాప్"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"వాలెట్ యాప్"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"వాలెట్ యాప్లు మీ క్రెడిట్ను, లాయల్టీ కార్డ్లను, కార్ కీలను, ఇంకా వివిధ రకాల లావాదేవీలకు సహాయపడటానికి ఇతర వస్తువులను స్టోర్ చేయగలవు."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను డిఫాల్ట్ వాలెట్ యాప్గా సెట్ చేయాలా?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"అనుమతులు ఏవీ అవసరం లేదు"</string> <string name="request_role_current_default" msgid="738722892438247184">"ప్రస్తుతం ఆటోమేటిక్గా ఉంది"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"మళ్లీ అడగవద్దు"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ఆటోమేటిక్ చేయండి"</string> @@ -610,9 +617,9 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"మైక్రోఫోన్ యాక్సెస్"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"యాప్లు, సర్వీస్ల కోసం"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"యాప్లు, సర్వీస్ల కోసం. ఈ సెట్టింగ్ ఆఫ్ చేయబడి ఉన్నట్లయితే, మీరు ఎమర్జెన్సీ నంబర్కు కాల్ చేసినప్పుడు మైక్రోఫోన్ డేటా ఇప్పటికీ షేర్ చేయబడవచ్చు."</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"లొకేషన్కు యాక్సెస్ ఉన్న యాప్లు, సర్వీస్లను చూడండి"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"లొకేషన్ యాక్సెస్ ఉన్న యాప్లను, సర్వీస్లను చూడండి"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"క్లిప్బోర్డ్ యాక్సెస్ను చూపించండి"</string> - <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"మీరు కాపీ చేసిన టెక్స్ట్, ఇమేజ్లను లేదా ఇతర కంటెంట్ను యాప్లు యాక్సెస్ చేసినప్పుడు మెసేజ్ను చూపుతుంది"</string> + <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"మీరు కాపీ చేసిన టెక్స్ట్ను, ఇమేజ్లను లేదా ఇతర కంటెంట్ను యాప్లు యాక్సెస్ చేసినప్పుడు ఒక మెసేజ్ను చూపుతుంది"</string> <string name="show_password_title" msgid="2877269286984684659">"పాస్వర్డ్లను చూపిస్తుంది"</string> <string name="show_password_summary" msgid="1110166488865981610">"మీరు టైప్ చేస్తున్నప్పుడు అక్షరాలను క్లుప్తంగా చూపిస్తుంది"</string> <string name="permission_rationale_message_location" msgid="2153841534298068414">"ఈ యాప్, అది లొకేషన్ డేటాను థర్డ్-పార్టీలతో షేర్ చేయవచ్చని పేర్కొంది"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"డేటా షేరింగ్ అప్డేట్లు"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"కొన్ని యాప్లు మీ లొకేషన్ డేటాను షేర్ చేయగల విధానాన్ని మార్చాయి"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"సెట్టింగ్లు"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>కు యాక్సెస్ చేశారు"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"నిన్న <xliff:g id="TIME_DATE">%1$s</xliff:g>కు యాక్సెస్ చేశారు"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g>న<xliff:g id="TIME_DATE_1">%2$s</xliff:g>కు యాక్సెస్ చేశారు"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"మీ ఒకసారి ఉపయోగించగల పాస్వర్డ్ 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"పరిమితం చేయబడిన సెట్టింగ్"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"మీ సెక్యూరిటీ కోసం, ఈ సెట్టింగ్ ప్రస్తుతం అందుబాటులో లేదు."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"యాప్ <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>కు యాక్సెస్ తిరస్కరించబడింది"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"మీ వ్యక్తిగత, ఆర్థిక సమాచారాన్ని ప్రమాదంలో పడేసే గోప్యమైన సమాచార యాక్సెస్ అనుమతికి యాప్ యాక్సెస్ను రిక్వెస్ట్ చేయడం జరిగింది.<xliff:g id="ID_1"><br><br></xliff:g>ఈ అదనపు అవసరాలు గల అనుమతి లేకుండా యాప్ సరిగ్గా పని చేయకపోయే అవకాశం ఉంది. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>యాక్సెస్ను అనుమతించడం ఎలాగో తెలుసుకోండి</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"యాప్ ఆటోమేటిక్ సెట్టింగ్ <xliff:g id="ROLE_NAME">%1$s</xliff:g>గా ఉండటానికి యాక్సెస్ తిరస్కరించబడింది"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"మీ వ్యక్తిగత, ఆర్థిక సమాచారాన్ని ప్రమాదంలో పడేసే గోప్యమైన సమాచార యాక్సెస్ అనుమతులకు యాప్ యాక్సెస్ను రిక్వెస్ట్ చేయడం జరిగింది.<xliff:g id="ID_1"><br><br></xliff:g>ఈ అదనపు అవసరాలు గల అనుమతులు లేకుండా యాప్ సరిగ్గా పని చేయకపోయే అవకాశం ఉంది. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>యాక్సెస్ను అనుమతించడం ఎలాగో తెలుసుకోండి</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"యాప్నకు యాక్సెస్ తిరస్కరించబడింది"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"ఈ అనుమతికి యాక్సెస్ను ఇవ్వడం వల్ల మీ వ్యక్తిగత, ఆర్థిక సమాచారం ప్రమాదంలో పడవచ్చు.<xliff:g id="ID_1"><br><br></xliff:g>ఈ అదనపు అవసరాలు గల అనుమతులు లేకుండా యాప్ సరిగ్గా పని చేయకపోయే అవకాశం ఉంది. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>యాక్సెస్ను అనుమతించడం ఎలాగో తెలుసుకోండి</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"మరింత తెలుసుకోండి"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"సరే"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"అనుమతి రిక్వెస్ట్ బ్లాక్ చేయబడింది"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"ఈ యాప్ అదనపు అనుమతి కోసం రిక్వెస్ట్ చేస్తోంది, కానీ స్ట్రీమింగ్ సెషన్లో అనుమతులను మంజూరు చేయడం సాధ్యం కాదు. ముందుగా మీ ఫోన్లో అనుమతిని మంజూరు చేయండి."</string> </resources> diff --git a/PermissionController/res/values-th-v34/strings.xml b/PermissionController/res/values-th-v34/strings.xml index 8e6bae837..7578fdb3c 100644 --- a/PermissionController/res/values-th-v34/strings.xml +++ b/PermissionController/res/values-th-v34/strings.xml @@ -20,8 +20,7 @@ <string name="security_privacy_brand_name" msgid="7303621734258440812">"ความปลอดภัยและความเป็นส่วนตัว"</string> <string name="privacy_subpage_controls_header" msgid="4152396976713749322">"การควบคุม"</string> <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> - <string name="health_connect_summary" msgid="815473513776882296">"จัดการสิทธิ์เข้าถึงข้อมูลสุขภาพของแอป"</string> + <string name="health_connect_summary" msgid="815473513776882296">"จัดการสิทธิ์ของแอปในการเข้าถึงข้อมูลสุขภาพ"</string> <string name="location_settings" msgid="8863940440881290182">"สิทธิ์เข้าถึงตำแหน่ง"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"สำหรับแอปและบริการ หากปิดการตั้งค่านี้ ระบบอาจยังคงแชร์ข้อมูลไมโครโฟนเมื่อคุณโทรหาหมายเลขฉุกเฉิน"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"สำหรับแอปและบริการ"</string> </resources> diff --git a/PermissionController/res/values-th-watch/strings.xml b/PermissionController/res/values-th-watch/strings.xml index db9d5dec6..8b6c60c76 100644 --- a/PermissionController/res/values-th-watch/strings.xml +++ b/PermissionController/res/values-th-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"เปลี่ยนไม่ได้"</string> <string name="generic_yes" msgid="2489207724988649846">"ใช่"</string> <string name="generic_cancel" msgid="2631708607129269698">"ยกเลิก"</string> + <string name="permission_access_always" msgid="2107115233573823032">"ตลอดเวลา"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ขณะกำลังใช้แอป"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"ตลอดเวลา"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ขณะกำลังใช้แอป"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"ตลอดเวลา"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ขณะกำลังใช้แอป"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"ตลอดเวลา"</string> </resources> diff --git a/PermissionController/res/values-th/strings.xml b/PermissionController/res/values-th/strings.xml index f960cfbaf..7674e2449 100644 --- a/PermissionController/res/values-th/strings.xml +++ b/PermissionController/res/values-th/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"สิทธิ์ทั้งหมด"</string> <string name="other_permissions" msgid="2901186127193849594">"ความสามารถอื่นๆ ของแอป"</string> <string name="permission_request_title" msgid="8790310151025020126">"คำขอสิทธิ์"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"ไม่สามารถติดตั้ง/ถอนการติดตั้งบน Wear"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"โปรดเลือกข้อมูลที่อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึง"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"อัปเดต <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> แล้ว โปรดเลือกข้อมูลที่อนุญาตให้แอปนี้เข้าถึง"</string> <string name="review_button_cancel" msgid="2191147944056548886">"ยกเลิก"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"แอปจะเข้าถึงตำแหน่งโดยประมาณเมื่อปิดใช้ตำแหน่งที่แน่นอน"</string> <string name="app_permission_title" msgid="2090897901051370711">"สิทธิ์เข้าถึง <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"สิทธิ์การเข้าถึง <xliff:g id="PERM">%1$s</xliff:g> สำหรับแอปนี้"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"สิทธิ์เข้าถึง<xliff:g id="PERM">%1$s</xliff:g>สำหรับแอปนี้บน <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"ดูสิทธิ์ทั้งหมดของ \"<xliff:g id="APP">%1$s</xliff:g>\""</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"ดูแอปทั้งหมดที่มีสิทธิ์นี้"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"แสดงการใช้ไมโครโฟนของ Assistant"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"นำสิทธิ์ออกหากไม่ได้ใช้งานแอป"</string> <string name="unused_apps_label" msgid="2595428768404901064">"นำสิทธิ์ออกและเพิ่มพื้นที่ว่าง"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"หยุดกิจกรรมบนแอปไว้ชั่วคราวหากไม่ได้ใช้"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"จัดการแอปหากไม่ได้ใช้งาน"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"นำสิทธิ์ออก ลบไฟล์ชั่วคราว และหยุดการแจ้งเตือน"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"นำสิทธิ์ออก ลบไฟล์ชั่วคราว หยุดการแจ้งเตือน และเก็บแอป"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"หากคุณไม่ได้ใช้งานแอปนาน 2-3 เดือน ระบบจะนำสิทธิ์ของแอปนี้ออกเพื่อปกป้องข้อมูลของคุณ"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"หากไม่มีการใช้งานแอปนาน 2-3 เดือน ระบบจะปกป้องข้อมูลของคุณด้วยการนำสิทธิ์ต่อไปนี้ออก ได้แก่ <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"ระบบนำสิทธิ์ออกจากแอปที่คุณไม่ได้ใช้งานนาน 2-3 เดือนเพื่อปกป้องข้อมูลของคุณ"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"ได้รับอนุญาตให้จัดการไฟล์ทั้งหมด"</string> <string name="ask_header" msgid="2633816846459944376">"ถามทุกครั้ง"</string> <string name="denied_header" msgid="903209608358177654">"ไม่อนุญาต"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>ใน <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"ดูแอปอื่นๆ ที่สามารถเข้าถึงไฟล์ทั้งหมดได้"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 วัน}other{# วัน}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# ชั่วโมง}other{# ชั่วโมง}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"แอปโน้ต"</string> <string name="role_notes_description" msgid="8496852798616883551">"แอปที่ให้คุณจดโน้ตในอุปกรณ์ได้"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"บันทึก"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"แอปกระเป๋าเงินเริ่มต้น"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"แอปกระเป๋าเงิน"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"แอปกระเป๋าเงินสามารถจัดเก็บบัตรเครดิต บัตรสะสมคะแนน กุญแจรถยนต์ รวมถึงสิ่งอื่นๆ เพื่อช่วยในการทำธุรกรรมรูปแบบต่างๆ"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"ตั้งค่า <xliff:g id="APP_NAME">%1$s</xliff:g> เป็นแอปกระเป๋าเงินเริ่มต้นไหม"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"ไม่ต้องใช้สิทธิ์"</string> <string name="request_role_current_default" msgid="738722892438247184">"แอปเริ่มต้นปัจจุบัน"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"ไม่ต้องถามอีก"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"ตั้งเป็นแอปเริ่มต้น"</string> @@ -461,10 +468,10 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงรายชื่อติดต่อไหม"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงรายชื่อติดต่อบน<b><xliff:g id="DEVICE">%2$s</xliff:g></b>ไหม"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของ<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>ไหม"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของ <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> ไหม"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"แอปจะมีสิทธิ์เข้าถึงตำแหน่งในขณะที่คุณใช้แอปเท่านั้น"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string> - <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของ<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>ไหม"</string> + <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของ <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g> ไหม"</string> <string name="permgroupbackgroundrequestdetail_location" msgid="8021219324989662957">"แอปนี้อาจต้องการเข้าถึงตำแหน่งของคุณตลอดเวลา แม้ในขณะที่คุณไม่ได้ใช้แอป โปรด"<annotation id="link">"อนุญาตในการตั้งค่า"</annotation></string> <string name="permgroupupgraderequest_location" msgid="8328408946822691636">"เปลี่ยนการเข้าถึงตำแหน่งสำหรับ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ไหม"</string> <string name="permgroupupgraderequest_device_aware_location" msgid="4528266408056426513">"เปลี่ยนแปลงสิทธิ์เข้าถึงตำแหน่งของ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> บน<b><xliff:g id="DEVICE">%2$s</xliff:g></b>ไหม"</string> @@ -610,7 +617,7 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"สิทธิ์เข้าถึงไมโครโฟน"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"สำหรับแอปและบริการ"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"สำหรับแอปและบริการ หากปิดการตั้งค่านี้ ระบบอาจยังคงแชร์ข้อมูลไมโครโฟนเมื่อคุณโทรหาหมายเลขฉุกเฉิน"</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"ดูแอปและบริการที่มีสิทธิ์เข้าถึงสถานที่ตั้ง"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"ดูแอปและบริการที่มีสิทธิ์เข้าถึงตำแหน่ง"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"แสดงการเข้าถึงคลิปบอร์ด"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"แสดงข้อความเมื่อแอปเข้าถึงข้อความ รูปภาพ หรือเนื้อหาอื่นๆ ที่คุณคัดลอก"</string> <string name="show_password_title" msgid="2877269286984684659">"แสดงรหัสผ่าน"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"การอัปเดตการแชร์ข้อมูล"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"มีบางแอปเปลี่ยนแปลงวิธีที่แอปอาจแชร์ข้อมูลตำแหน่งของคุณ"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"การตั้งค่า"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"เข้าถึงตอน <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"เข้าถึงเมื่อวานตอน <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"เข้าถึงเมื่อวันที่ <xliff:g id="TIME_DATE_0">%1$s</xliff:g> ตอน <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"รหัสผ่านที่สามารถใช้งานได้เพียงครั้งเดียวของคุณคือ 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"การตั้งค่าที่จำกัด"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"การตั้งค่านี้ใช้ไม่ได้ในตอนนี้เพื่อความปลอดภัยของคุณ"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"แอปถูกปฏิเสธไม่ให้เข้าถึง <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"แอปขอเข้าถึงสิทธิ์ที่มีความละเอียดอ่อนซึ่งอาจทำให้ข้อมูลส่วนบุคคลและข้อมูลทางการเงินของคุณมีความเสี่ยง<xliff:g id="ID_1"><br><br></xliff:g>แอปอาจทำงานได้ไม่ถูกต้องหากไม่มีสิทธิ์ที่จำกัดนี้ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ดูวิธีอนุญาตให้เข้าถึง</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"แอปถูกปฏิเสธไม่ให้เข้าถึงเพื่อเป็น <xliff:g id="ROLE_NAME">%1$s</xliff:g> เริ่มต้น"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"แอปขอเข้าถึงสิทธิ์ที่มีความละเอียดอ่อนซึ่งอาจทำให้ข้อมูลส่วนบุคคลและข้อมูลทางการเงินของคุณมีความเสี่ยง<xliff:g id="ID_1"><br><br></xliff:g>แอปอาจทำงานได้ไม่ถูกต้องหากไม่มีสิทธิ์ที่จำกัดเหล่านี้ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ดูวิธีอนุญาตให้เข้าถึง</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"แอปถูกปฏิเสธไม่ให้เข้าถึง"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"การให้สิทธิ์นี้อาจทำให้ข้อมูลส่วนบุคคลและข้อมูลทางการเงินของคุณมีความเสี่ยง<xliff:g id="ID_1"><br><br></xliff:g>แอปอาจทำงานได้ไม่ถูกต้องหากไม่มีสิทธิ์ที่จำกัดนี้ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>ดูวิธีอนุญาตให้เข้าถึง</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"ดูข้อมูลเพิ่มเติม"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ตกลง"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"ระงับคำขอสิทธิ์อยู่"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"แอปนี้มีการขอสิทธิ์เพิ่มเติม แต่ไม่สามารถให้สิทธิ์ในเซสชันที่กำลังสตรีมอยู่ โปรดให้สิทธิ์ในโทรศัพท์ก่อน"</string> </resources> diff --git a/PermissionController/res/values-tl-v34/strings.xml b/PermissionController/res/values-tl-v34/strings.xml index 4ed588f80..a0b9e58d4 100644 --- a/PermissionController/res/values-tl-v34/strings.xml +++ b/PermissionController/res/values-tl-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Pamahalaan ang access ng app sa data ng kalusugan"</string> <string name="location_settings" msgid="8863940440881290182">"Access sa lokasyon"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Para sa mga app at serbisyo. Kung naka-off ang setting na ito, posible pa ring ibahagi ang data ng mikropono kapag tumawag ka sa isang pang-emergency na numero"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Para sa mga app at serbisyo"</string> </resources> diff --git a/PermissionController/res/values-tl-watch/strings.xml b/PermissionController/res/values-tl-watch/strings.xml index 1719c5c5e..33191f04f 100644 --- a/PermissionController/res/values-tl-watch/strings.xml +++ b/PermissionController/res/values-tl-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Hindi mababago"</string> <string name="generic_yes" msgid="2489207724988649846">"Oo"</string> <string name="generic_cancel" msgid="2631708607129269698">"Kanselahin"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Palagi"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Habang ginagamit ang app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Palagi"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Habang ginagamit ang app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Palagi"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Habang ginagamit ang app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Palagi"</string> </resources> diff --git a/PermissionController/res/values-tl/strings.xml b/PermissionController/res/values-tl/strings.xml index c17871ae5..fbaf81796 100644 --- a/PermissionController/res/values-tl/strings.xml +++ b/PermissionController/res/values-tl/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Lahat ng pahintulot"</string> <string name="other_permissions" msgid="2901186127193849594">"Iba pang kakayahan ng app"</string> <string name="permission_request_title" msgid="8790310151025020126">"Kahilingan sa pagpapahintulot"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Ang mga pagkilos na I-install/I-uninstall ay hindi sinusuportahan sa Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Piliin kung ano ang papayagang i-access ng <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Na-update na ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Piliin kung ano ang papayagang i-access ng app na ito."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Kanselahin"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Kapag naka-off ang eksaktong lokasyon, puwedeng i-access ng mga app ang iyong tinatantyang lokasyon"</string> <string name="app_permission_title" msgid="2090897901051370711">"Pahintulot sa <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Access sa <xliff:g id="PERM">%1$s</xliff:g> para sa app na ito"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"access sa <xliff:g id="PERM">%1$s</xliff:g> para sa app na ito sa <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Tingnan ang lahat ng pahintulot ng <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Tingnan ang lahat ng app na may ganitong pahintulot"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Ipakita ang paggamit ng mikropono ng assistant"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Alisin ang mga pahintulot kung hindi ginagamit ang app"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Alisin ang pahintulot, magbakante ng espasyo"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"I-pause ang aktibidad sa app kung hindi ginagamit"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Pamahalaan ang app kung hindi ginagamit"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Alisin ang mga pahintulot, i-delete ang mga pansamantalang file, at ihinto ang mga notification"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Alisin ang mga pahintulot, i-delete ang mga pansamantalang file, ihinto ang mga notification, at i-archive ang app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para maprotektahan ang iyong data, aalisin ang mga pahintulot para sa app na ito kapag ilang buwan nang hindi ginagamit ang app."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para maprotektahan ang iyong data, kapag ilang buwan nang hindi ginagamit ang app, aalisin ang mga sumusunod na pahintulot: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para protektahan ang iyong data, inalis na ang mga pahintulot sa mga app na ilang buwan mo nang hindi ginagamit."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Pinapayagang pamahalaan ang lahat ng file"</string> <string name="ask_header" msgid="2633816846459944376">"Magtanong palagi"</string> <string name="denied_header" msgid="903209608358177654">"Hindi pinapayagan"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> noong <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Tumingin pa ng mga app na puwedeng mag-access ng lahat ng file"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 araw}one{# araw}other{# na araw}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# oras}one{# oras}other{# na oras}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notes app"</string> <string name="role_notes_description" msgid="8496852798616883551">"Mga app na nagbibigay-daan sa iyong magtala sa device mo"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"mga tala"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Default na wallet app"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Wallet app"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Puwedeng i-store ng mga wallet app ang iyong mga credit at loyalty card, susi ng kotse, at iba pang bagay para makatulong sa iba\'t ibang uri ng transaksyon."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Itakda ang <xliff:g id="APP_NAME">%1$s</xliff:g> bilang default mong wallet app?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Walang kailangang pahintulot"</string> <string name="request_role_current_default" msgid="738722892438247184">"Kasalukuyang default"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Huwag nang itanong muli"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Itakdang default"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na i-access ang iyong mga contact?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na i-access ang iyong mga contact sa <b><xliff:g id="DEVICE">%2$s</xliff:g></b> mo?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na i-access ang lokasyon ng device na ito?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na i-access ang lokasyon ng <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b> mo?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na i-access ang lokasyon ng <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b> mo?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Magkakaroon lang ang app ng access sa lokasyon habang ginagamit mo ang app"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na i-access ang lokasyon ng device na ito?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na i-access ang lokasyon ng <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g> mo?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Update sa pagbabahagi ng data"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Binago ng ilang app kung paano posibleng ibahagi ng mga ito ang iyong data ng lokasyon"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Mga Setting"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Na-access noong <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Na-access kahapon nang <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Na-access noong <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Ang iyong pang-isang beses na password ay 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Pinaghihigpitang setting"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Para sa iyong seguridad, hindi available ang setting na ito sa ngayon."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Tinanggihan ang access ng appp sa <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Humiling ang app ng access sa pahintulot sa sensitibong impormasyon na posibleng maglagay ng iyong personal at pinansyal na impormasyon sa panganib.<xliff:g id="ID_1"><br><br></xliff:g>Posibleng hindi gumana nang maayos ang app kung wala ang pinaghihigpitang pahintulot na ito. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Alamin kung paano payagan ang pag-access</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Tinanggihan ang access ng app na maging default na <xliff:g id="ROLE_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Humiling ang app ng access sa mga pahintulot sa sensitibong impormasyon na posibleng maglagay ng iyong personal at pinansyal na impormasyon sa panganib.<xliff:g id="ID_1"><br><br></xliff:g>Posibleng hindi gumana nang maayos ang app kung wala ang mga pinaghihigpitang pahintulot na ito. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Alamin kung paano payagan ang pag-access</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Tinanggihan ang access ng app"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Puwedeng ilagay sa panganib ng pag-access sa pahintulot na ito ang iyong personal at pinansyal na impormasyon.<xliff:g id="ID_1"><br><br></xliff:g>Posibleng hindi gumana nang maayos ang app kung wala ang pinaghihigpitang pahintulot na ito. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Alamin kung paano payagan ang pag-access</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Matuto pa"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Pinigilan ang kahilingan sa pahintulot"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Humihingi ang app na ito ng dagdag na pahintulot, pero hindi puwedeng ibigay ang mga pahintulot sa isang session ng streaming. Ibigay muna ang pahintulot sa iyong telepono."</string> </resources> diff --git a/PermissionController/res/values-tr-v34/strings.xml b/PermissionController/res/values-tr-v34/strings.xml index 81d533562..95f5539d4 100644 --- a/PermissionController/res/values-tr-v34/strings.xml +++ b/PermissionController/res/values-tr-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Uygulamaların, sağlık verilerine erişimini yönetin"</string> <string name="location_settings" msgid="8863940440881290182">"Konum erişimi"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Uygulamalar ve hizmetler için. Bu ayar kapalıyken bir acil durum numarasını aradığınızda mikrofon verileri paylaşılmaya devam edebilir."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Uygulamalar ve hizmetler için"</string> </resources> diff --git a/PermissionController/res/values-tr-watch/strings.xml b/PermissionController/res/values-tr-watch/strings.xml index d4845f76b..bdba397ff 100644 --- a/PermissionController/res/values-tr-watch/strings.xml +++ b/PermissionController/res/values-tr-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Değiştirilemez"</string> <string name="generic_yes" msgid="2489207724988649846">"Evet"</string> <string name="generic_cancel" msgid="2631708607129269698">"İptal"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Her zaman"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Uygulama kullanılırken"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Her zaman"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Uygulama kullanılırken"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Her zaman"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Uygulama kullanılırken"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Her zaman"</string> </resources> diff --git a/PermissionController/res/values-tr/strings.xml b/PermissionController/res/values-tr/strings.xml index 878e9155c..61522e980 100644 --- a/PermissionController/res/values-tr/strings.xml +++ b/PermissionController/res/values-tr/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Tüm izinler"</string> <string name="other_permissions" msgid="2901186127193849594">"Diğer uygulama özellikleri"</string> <string name="permission_request_title" msgid="8790310151025020126">"İzin isteği"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Yükleme/Yüklemeyi Kaldırma işlemleri Wear\'da desteklenmiyor."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uygulamasının nelere erişmesine izin vereceğinizi seçin"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> güncellendi. Bu uygulamanın nelere erişmesine izin verileceğini seçin."</string> <string name="review_button_cancel" msgid="2191147944056548886">"İptal"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Tam konum kapalıyken uygulamalar, yaklaşık konumunuza erişebilir"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> izni"</string> <string name="app_permission_header" msgid="2951363137032603806">"Bu uygulamanın <xliff:g id="PERM">%1$s</xliff:g> erişimi için"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> adlı cihazda bu uygulamanın <xliff:g id="PERM">%1$s</xliff:g> erişimi"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Tüm <xliff:g id="APP">%1$s</xliff:g> izinlerini göster"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Bu izne sahip tüm uygulamaları göster"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Yardımcı mikrofon kullanımını göster"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Uygulama kullanılmıyorsa izinleri kaldır"</string> <string name="unused_apps_label" msgid="2595428768404901064">"İzinleri kaldırıp yer aç"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Kullanılmayan uygulama etkinliğini duraklat"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Kullanılmayan uygulamayı yönet"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"İzinleri kaldır, geçici dosyaları sil ve bildirimleri durdur"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"İzinleri kaldır, geçici dosyaları sil, bildirimleri durdur ve uygulamayı arşivle"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Bu uygulama birkaç ay boyunca kullanılmazsa verilerinizi korumak için uygulamanın izinleri kaldırılır."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Uygulama birkaç ay boyunca kullanılmazsa şu izinler verilerinizi korumak için kaldırılacak: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Birkaç aydır kullanmadığınız uygulamaların izinleri verilerinizi korumak için kaldırıldı."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Tüm dosyaları yönetme izni verilenler"</string> <string name="ask_header" msgid="2633816846459944376">"Her zaman sorulacaklar"</string> <string name="denied_header" msgid="903209608358177654">"İzin verilmeyenler"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazında <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Tüm dosyalara erişebilen diğer uygulamaları görün"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 gün}other{# gün}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# saat}other{# saat}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Notlar uygulaması"</string> <string name="role_notes_description" msgid="8496852798616883551">"Cihazınızda not almanıza olanak tanıyan uygulamalar"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"notlar"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Varsayılan cüzdan uygulaması"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Cüzdan uygulaması"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Cüzdan uygulamaları; kredi ve bağlılık kartlarınızı, araba anahtarlarınızı ve diğer bilgileri depolayarak çeşitli işlem türlerinde size kolaylık sağlayabilir."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g>, varsayılan cüzdan uygulamanız olarak ayarlansın mı?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Herhangi bir izin gerekli değil"</string> <string name="request_role_current_default" msgid="738722892438247184">"Mevcut varsayılan"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Tekrar sorma"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Varsayılan olarak ayarla"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Veri paylaşımı güncellemeleri"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Bazı uygulamalar, konum verilerinizi paylaşma şeklini değiştirdi"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Ayarlar"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Erişim zamanı: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Dün saat <xliff:g id="TIME_DATE">%1$s</xliff:g> itibarıyla erişildi"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Erişim tarihi: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Tek kullanımlık şifreniz 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Kısıtlanmış ayar"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Güvenliğiniz için bu ayar şu anda kullanılamıyor."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Uygulamanın <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> iznine erişimi reddedildi"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Uygulama, kişisel ve finansal bilgilerinizi riske atabilecek hassas bir izne erişim istedi.<xliff:g id="ID_1"><br><br></xliff:g>Bu kısıtlı izin olmadan uygulama düzgün çalışmayabilir. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Erişime nasıl izin vereceğinizi öğrenin</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Uygulamanın varsayılan <xliff:g id="ROLE_NAME">%1$s</xliff:g> olarak kullanılma erişimi reddedildi"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Uygulama, kişisel ve finansal bilgilerinizi riske atabilecek hassas izinlere erişim istedi.<xliff:g id="ID_1"><br><br></xliff:g>Bu kısıtlı izinler olmadan uygulama düzgün çalışmayabilir. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Erişime nasıl izin vereceğinizi öğrenin</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Uygulamanın erişimi reddedildi"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Bu izne erişim, kişisel ve finansal bilgilerinizi riske atabilir.<xliff:g id="ID_1"><br><br></xliff:g>Bu kısıtlı izin olmadan uygulama düzgün çalışmayabilir. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Erişime nasıl izin vereceğinizi öğrenin</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Daha fazla bilgi edinin"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Tamam"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"İzin isteği reddedildi"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Bu uygulama ek izinler istiyor ancak akış oturumundayken izin verilemez. Önce telefonunuzda ilgili izni verin."</string> </resources> diff --git a/PermissionController/res/values-uk-v34/strings.xml b/PermissionController/res/values-uk-v34/strings.xml index 5d14c8ebe..b40b556f4 100644 --- a/PermissionController/res/values-uk-v34/strings.xml +++ b/PermissionController/res/values-uk-v34/strings.xml @@ -17,11 +17,10 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="security_privacy_brand_name" msgid="7303621734258440812">"Безпека й конфіденційність"</string> + <string name="security_privacy_brand_name" msgid="7303621734258440812">"Захист і конфіденційність"</string> <string name="privacy_subpage_controls_header" msgid="4152396976713749322">"Параметри"</string> <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> <string name="health_connect_summary" msgid="815473513776882296">"Керуйте доступом додатків до даних про здоров’я"</string> <string name="location_settings" msgid="8863940440881290182">"Доступ до геоданих"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Для додатків і сервісів. Якщо це налаштування вимкнено, дані мікрофона можуть усе одно передаватися під час виклику екстреного номера."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Для додатків і сервісів"</string> </resources> diff --git a/PermissionController/res/values-uk-watch/strings.xml b/PermissionController/res/values-uk-watch/strings.xml index 244c24ec8..e83f408ef 100644 --- a/PermissionController/res/values-uk-watch/strings.xml +++ b/PermissionController/res/values-uk-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Не можна змінити"</string> <string name="generic_yes" msgid="2489207724988649846">"Так"</string> <string name="generic_cancel" msgid="2631708607129269698">"Скасувати"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Завжди"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Під час використ. додатка"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Завжди"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Під час використ. додатка"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Завжди"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Під час використ. додатка"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Завжди"</string> </resources> diff --git a/PermissionController/res/values-uk/strings.xml b/PermissionController/res/values-uk/strings.xml index 9a39e12ee..78504df9b 100644 --- a/PermissionController/res/values-uk/strings.xml +++ b/PermissionController/res/values-uk/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Усі дозволи"</string> <string name="other_permissions" msgid="2901186127193849594">"Інші дозволи додатка"</string> <string name="permission_request_title" msgid="8790310151025020126">"Запит на дозвіл"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Встановлення й видалення не підтримуються на пристроях Android Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Виберіть, до чого додаток <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> матиме доступ"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Додаток <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> оновлено. Виберіть, до чого він матиме доступ."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Скасувати"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Якщо вимкнено доступ до точного місцезнаходження, додатки можуть отримувати дані про приблизне"</string> <string name="app_permission_title" msgid="2090897901051370711">"Дозвіл \"<xliff:g id="PERM">%1$s</xliff:g>\""</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: доступ для цього додатка"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="PERM">%1$s</xliff:g>: доступ для цього додатка (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Переглянути всі дозволи додатка <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Переглянути всі додатки з цим дозволом"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Показати статус мікрофона Асистента"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Відкликати дозволи, якщо додаток не використовується"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Вилучати дозволи й звільняти місце"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Призупиняти роботу в неактивний період"</string> - <string name="unused_apps_summary" msgid="8839466950318403115">"Вилучити дозволи, видалити тимчасові файли та зупинити сповіщення"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Керувати невикористовуваним додатком"</string> + <string name="unused_apps_summary" msgid="8839466950318403115">"Вилучити дозволи, видалити тимчасові файли й зупинити сповіщення"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Вилучити дозволи, видалити тимчасові файли, зупинити сповіщення й архівувати додаток"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Щоб захистити ваші дані, дозволи для цього додатка буде автоматично скасовано, якщо ви не будете користуватися ним кілька місяців."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Якщо додаток не використовується впродовж кількох місяців, для захисту ваших даних буде скасовано такі дозволи: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Щоб захистити ваші дані, було скасовано дозволи додатків, які не використовувалися впродовж кількох місяців."</string> @@ -232,7 +233,7 @@ <string name="permission_description_summary_activity_recognition" msgid="2652850576497070146">"Додатки з цим дозволом мають доступ до даних про вашу фізичну активність (ходьбу, поїздки на велосипеді й автомобілі, кількість кроків тощо)"</string> <string name="permission_description_summary_calendar" msgid="103329982944411010">"Додатки з цим дозволом мають доступ до вашого календаря"</string> <string name="permission_description_summary_call_log" msgid="7321437186317577624">"Додатки з цим дозволом можуть переглядати й редагувати ваш журнал викликів"</string> - <string name="permission_description_summary_camera" msgid="108004375101882069">"Додатки з цим дозволом можуть робити знімки та записувати відео"</string> + <string name="permission_description_summary_camera" msgid="108004375101882069">"Додатки з цим дозволом можуть робити знімки й записувати відео"</string> <string name="permission_description_summary_contacts" msgid="2337798886460408996">"Додатки з цим дозволом мають доступ до ваших контактів"</string> <string name="permission_description_summary_location" msgid="2817531799933480694">"Додатки з цим дозволом мають доступ до геоданих цього пристрою"</string> <string name="permission_description_summary_nearby_devices" msgid="8269183818275073741">"Додатки з цим дозволом можуть знаходити пристрої поблизу, підключатися до них і визначати їх відносне розташування."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Можуть керувати всіма файлами"</string> <string name="ask_header" msgid="2633816846459944376">"Запитувати щоразу"</string> <string name="denied_header" msgid="903209608358177654">"Заборонено"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>)"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Переглянути інші додатки, які мають доступ до всіх файлів"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 день}one{# день}few{# дні}many{# днів}other{# дня}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# година}one{# година}few{# години}many{# годин}other{# години}}"</string> @@ -353,7 +355,7 @@ <string name="role_assistant_short_label" msgid="3369003713187703399">"Цифровий помічник"</string> <string name="role_assistant_description" msgid="6622458130459922952">"Помічники надають допомогу на основі вмісту, який ви переглядаєте на екрані. Задля ефективності деякі додатки підтримують панель запуску й голосовий ввід."</string> <string name="role_browser_label" msgid="2877796144554070207">"Веб-переглядач за умовчанням"</string> - <string name="role_browser_short_label" msgid="6745009127123292296">"Веб-переглядач"</string> + <string name="role_browser_short_label" msgid="6745009127123292296">"Вебпереглядач"</string> <string name="role_browser_description" msgid="3465253637499842671">"Додатки, за допомогою яких можна переглядати сайти й переходити за посиланнями"</string> <string name="role_browser_request_title" msgid="2895200507835937192">"Зробити <xliff:g id="APP_NAME">%1$s</xliff:g> веб-переглядачем за умовчанням?"</string> <string name="role_browser_request_description" msgid="5888803407905985941">"Дозволи не потрібні"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Додаток для нотаток"</string> <string name="role_notes_description" msgid="8496852798616883551">"Додатки, у яких можна робити нотатки на вашому пристрої"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"нотатки"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Гаманець за умовчанням"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Гаманець"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"У гаманцях можуть зберігатися ваші картки постійного покупця й кредитні картки, автомобільні ключі та інші об’єкти, які полегшують здійснення різних трансакцій."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Зробити додаток <xliff:g id="APP_NAME">%1$s</xliff:g> гаманцем за умовчанням?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Дозволи не потрібні"</string> <string name="request_role_current_default" msgid="738722892438247184">"Поточний за умовчанням"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Не запитувати знову"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Вибрати за умовчанням"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до контактів?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до контактів на <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до місцезнаходження пристрою?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до місцезнаходження на <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до даних про місцезнаходження на пристрої <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Додаток матиме доступ до геоданих, лише коли ви ним користуєтеся"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до місцезнаходження пристрою?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до геоданих на <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"Цей додаток може записувати звук, навіть коли ви не використовуєте його. Дозвіл можна надати в "<annotation id="link">"налаштуваннях"</annotation>"."</string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"Надати додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до даних про фізичну активність?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до даних про фізичну активність на <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> робити знімки та записувати відео?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> робити знімки й записувати відео?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> робити знімки й записувати відео на <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"Додаток зможе робити фотографії та записувати відео, лише коли ви використовуєте його"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> робити знімки й записувати відео?"</string> @@ -514,7 +521,7 @@ <string name="permgroupupgraderequestdetail_camera" msgid="6642747548010962597">"Цей додаток може робити фотографії та записувати відео, навіть коли ви не використовуєте його. Дозвіл можна надати в "<annotation id="link">"налаштуваннях"</annotation>"."</string> <string name="permgrouprequest_calllog" msgid="2065327180175371397">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до журналів викликів телефона?"</string> <string name="permgrouprequest_device_aware_calllog" msgid="735079772627778095">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до журналів викликів на <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_phone" msgid="1829234136997316752">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> здійснювати телефонні дзвінки та керувати ними?"</string> + <string name="permgrouprequest_phone" msgid="1829234136997316752">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> здійснювати телефонні дзвінки й керувати ними?"</string> <string name="permgrouprequest_device_aware_phone" msgid="4389610977195521813">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> здійснювати телефонні дзвінки й керувати ними на <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_sensors" msgid="4397358316850652235">"Надати додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до життєвих показників із датчиків?"</string> <string name="permgrouprequest_device_aware_sensors" msgid="1900598688488188225">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> доступ до життєвих показників від датчиків на <b><xliff:g id="DEVICE">%2$s</xliff:g></b>?"</string> @@ -610,7 +617,7 @@ <string name="mic_toggle_title" msgid="2649991093496110162">"Доступ до мікрофона"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Для додатків і сервісів"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Для додатків і сервісів. Якщо це налаштування вимкнено, дані мікрофона можуть усе одно передаватися під час виклику екстреного номера."</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"Перегляньте додатки та сервіси, які мають доступ до геоданих"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"Перегляньте додатки й сервіси, які мають доступ до геоданих"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"Показувати сповіщення про доступ до буфера обміну"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"З’являтиметься сповіщення, коли будь-який додаток отримуватиме доступ до скопійованого вами тексту, зображень чи іншого контенту"</string> <string name="show_password_title" msgid="2877269286984684659">"Показувати паролі"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Оновлення способу передавання даних"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Деякі додатки змінили спосіб передавання ваших геоданих"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Налаштування"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Доступ отримано: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Доступ отримано вчора: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Доступ отримано: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Ваш одноразовий пароль: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Налаштування з обмеженнями"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"З міркувань безпеки це налаштування наразі недоступне."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Додатку не надано дозвіл \"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>\""</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Додаток запитав дозвіл на доступ до чутливих даних, що може поставити під загрозу вашу особисту й фінансову інформацію.<xliff:g id="ID_1"><br><br></xliff:g>Без цього обмеженого дозволу додаток може не працювати належним чином. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Як надати доступ</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Додатку не надано доступ до ролі \"<xliff:g id="ROLE_NAME">%1$s</xliff:g>\" за умовчанням"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Додаток запитав дозволи на доступ до чутливих даних, що може поставити під загрозу вашу особисту й фінансову інформацію.<xliff:g id="ID_1"><br><br></xliff:g>Без цих обмежених дозволів додаток може не працювати належним чином. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Як надати доступ</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Додатку не надано доступ"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Доступ до цього дозволу може поставити під загрозу вашу особисту й фінансову інформацію.<xliff:g id="ID_1"><br><br></xliff:g>Без цього обмеженого дозволу додаток може не працювати належним чином. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Як надати доступ</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Докладніше"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ОК"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Запит на доступ відхилено"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Цьому додатку потрібні додаткові дозволи, але їх не можна надати під час потокового передавання. Спершу надайте дозвіл на телефоні."</string> </resources> diff --git a/PermissionController/res/values-ur-v34/strings.xml b/PermissionController/res/values-ur-v34/strings.xml index 37b5ec635..f7aa633cb 100644 --- a/PermissionController/res/values-ur-v34/strings.xml +++ b/PermissionController/res/values-ur-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"صحت کے ڈیٹا تک ایپ کی رسائی کا نظم کریں"</string> <string name="location_settings" msgid="8863940440881290182">"مقام تک رسائی"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"ایپس اور سروسز کے لیے۔ اگر یہ ترتیب آف ہو تو آپ کے ایمرجنسی نمبر پر کال کرتے وقت بھی مائیکروفون کے ڈیٹا کا اشتراک کیا جا سکتا ہے"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"ایپس اور سروسز کے لیے"</string> </resources> diff --git a/PermissionController/res/values-ur-watch/strings.xml b/PermissionController/res/values-ur-watch/strings.xml index bb0273bc4..1dab4010d 100644 --- a/PermissionController/res/values-ur-watch/strings.xml +++ b/PermissionController/res/values-ur-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"ناقابل تبدیل"</string> <string name="generic_yes" msgid="2489207724988649846">"ہاں"</string> <string name="generic_cancel" msgid="2631708607129269698">"منسوخ کریں"</string> + <string name="permission_access_always" msgid="2107115233573823032">"ہر وقت"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"ایپ استعمال کرنے کے دوران"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"ہر وقت"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"ایپ استعمال کرنے کے دوران"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"ہر وقت"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"ایپ استعمال کرنے کے دوران"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"ہر وقت"</string> </resources> diff --git a/PermissionController/res/values-ur/strings.xml b/PermissionController/res/values-ur/strings.xml index f1d9a96dc..d80d6d2cb 100644 --- a/PermissionController/res/values-ur/strings.xml +++ b/PermissionController/res/values-ur/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"تمام اجازتیں"</string> <string name="other_permissions" msgid="2901186127193849594">"ایپ کی دوسری اہلیتیں"</string> <string name="permission_request_title" msgid="8790310151025020126">"اجازت کی درخواست"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"\'کارروائیاں انسٹال/اَن انسٹال کریں\' Wear پر تعاون یافتہ نہیں ہے۔"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"منتخب کریں کہ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> کو کس چیز تک رسائی کی اجازت دینی ہے"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> اپ ڈیٹ ہو گئی ہے۔ منتخب کریں کہ اس ایپ کو کس تک رسائی کی اجازت دینی ہے۔"</string> <string name="review_button_cancel" msgid="2191147944056548886">"منسوخ کریں"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"قطعی مقام آف ہونے پر ایپس آپ کے تخمینی مقام تک رسائی حاصل کر سکتی ہیں"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> کی اجازت"</string> <string name="app_permission_header" msgid="2951363137032603806">"اس ایپ کیلئے <xliff:g id="PERM">%1$s</xliff:g> تک رسائی"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> پر اس ایپ تک رسائی حاصل کریں<xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g> کی سبھی اجازتیں دیکھیں"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"اس اجازت والی سبھی ایپس دیکھیں"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"اسسٹنٹ مائیکروفون کا استعمال دکھائیں"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ایپ کے استعمال نہ ہونے پر اجازتیں ہٹائیں"</string> <string name="unused_apps_label" msgid="2595428768404901064">"اجازتوں کو ہٹائیں اور جگہ خالی کریں"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"غیر استعمال شدہ ہو تو ایپ سرگرمی روکیں"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"اگر غیر استعمال شدہ ہے تو ایپ کا نظم کریں"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"اجازتیں ہٹائیں، عارضی فائلز حذف کریں اور اطلاعات موقوف کریں"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"اجازتیں ہٹائیں، عارضی فائلوں کو حذف کریں، اطلاعات کو روکیں اور ایپ کو آرکائیو کریں"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"آپ کے ڈیٹا کی حفاظت کے لیے، اگر ایپ کو کچھ مہینوں تک استعمال نہیں کیا گیا تو اس ایپ کے لیے اجازتیں ہٹا دی جائیں گی۔"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"آپ کے ڈیٹا کی حفاظت کے لیے، اگر ایپ کو کچھ مہینوں تک استعمال نہیں کیا گيا تو درج ذیل اجازتیں ہٹا دی جائیں گی: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"آپ کے ڈیٹا کی حفاظت کے لیے، اجازتوں کو ان ایپس سے ہٹا دیا گیا ہے جنہیں آپ نے کچھ مہینوں سے استعمال نہیں کیا ہے۔"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"سبھی فائلز کا نظم کرنے کے ليے اجازت یافتہ"</string> <string name="ask_header" msgid="2633816846459944376">"ہر بار پوچھیں"</string> <string name="denied_header" msgid="903209608358177654">"اجازت نہیں ہے"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> پر <xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"مزید ایپس دیکھیں جو تمام فائلز تک رسائی حاصل کر سکتی ہیں"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 دن}other{# دن}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# گھنٹہ}other{# گھنٹے}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"نوٹس ایپ"</string> <string name="role_notes_description" msgid="8496852798616883551">"ایسی ایپس جو آپ کو آپ کے آلے پر نوٹس لینے کی اجازت دیتی ہیں"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"نوٹس"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"ڈیفالٹ والٹ ایپ"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"والٹ ایپ"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"والٹ ایپس آپ کے کریڈٹ اور لائلٹی کارڈز، کار کی کلیدوں اور دیگر چیزوں کو ٹرانزیکشنز کی مختلف شکلوں میں مدد کے لیے اسٹور کر سکتی ہیں۔"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو آپ کی ڈیفالٹ والٹ ایپ کے طور پر سیٹ کریں؟"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"کوئی اجازت درکار نہیں ہے"</string> <string name="request_role_current_default" msgid="738722892438247184">"موجودہ ڈیفالٹ"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"دوبارہ نہ پوچھیں"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"بطور ڈیفالٹ سیٹ کریں"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"ڈیٹا کے اشتراک کی اپ ڈیٹس"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"کچھ ایپس نے آپ کے مقام کے ڈیٹا کے اشتراک کے اپنے ممکنہ طریقے کو تبدیل کر دیا"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"ترتیبات"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g> پر رسائی حاصل کی گئی"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"گزشتہ کل <xliff:g id="TIME_DATE">%1$s</xliff:g> پر رسائی حاصل کی گئی"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g> پر رسائی حاصل کی گئی"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"آپ کا ایک وقتی پاس ورڈ 132435 ہے"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"محدود ترتیب"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"آپ کی سیکیورٹی کیلئے، یہ ترتیب فی الحال دستیاب نہیں ہے۔"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g> تک ایپ کی رسائی کو مسترد کر دیا گیا"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"ایپ نے ایک حساس اجازت تک رسائی کی درخواست کی ہے جو آپ کی ذاتی اور مالی معلومات کو خطرے میں ڈال سکتی ہے۔<xliff:g id="ID_1"><br><br></xliff:g>یہ ممکن ہے کہ اس محدود اجازت کے بغیر ایپ ٹھیک سے کام نہ کرے۔ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>رسائی کی اجازت دینے کا طریقہ جانیں</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"ڈیفالٹ <xliff:g id="ROLE_NAME">%1$s</xliff:g> ہونے کے لیے ایپ کی رسائی کو مسترد کر دیا گیا"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"ایپ نے حساس اجازتوں تک رسائی کی درخواست کی ہے جو آپ کی ذاتی اور مالی معلومات کو خطرے میں ڈال سکتی ہیں۔<xliff:g id="ID_1"><br><br></xliff:g>یہ ممکن ہے کہ ان محدود اجازتوں کے بغیر ایپ ٹھیک سے کام نہ کرے۔ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>رسائی کی اجازت دینے کا طریقہ جانیں</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"ایپ کی رسائی کو مسترد کر دیا گیا"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"اس اجازت تک رسائی آپ کی ذاتی اور مالی معلومات کو خطرے میں ڈال سکتی ہے۔<xliff:g id="ID_1"><br><br></xliff:g>یہ ممکن ہے کہ اس محدود اجازت کے بغیر ایپ ٹھیک سے کام نہ کرے۔ <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>رسائی کی اجازت دینے کا طریقہ جانیں</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"مزید جانیں"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"ٹھیک ہے"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"اجازت کی درخواست مسترد کر دی گئی"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"یہ ایپ اضافی اجازتوں کی درخواست کر رہی ہے، لیکن سلسلہ بندی کے سیشن میں اجازتیں نہیں دی جا سکتیں۔ پہلے اپنے فون پر اجازت دیں۔"</string> </resources> diff --git a/PermissionController/res/values-uz-v34/strings.xml b/PermissionController/res/values-uz-v34/strings.xml index 3c48cd9d1..21388d616 100644 --- a/PermissionController/res/values-uz-v34/strings.xml +++ b/PermissionController/res/values-uz-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Salomatlik maʼlumotlariga ilova ruxsatini boshqaring"</string> <string name="location_settings" msgid="8863940440881290182">"Joylashuv axborotiga ruxsat"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Ilovalar va xizmatlar uchun. Bu sozlama yoqilmasa, favqulodda xizmat raqamiga telefon qilganingizda mikrofon maʼlumotlari hamon ulashilishi mumkin"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Ilovalar va xizmatlar uchun"</string> </resources> diff --git a/PermissionController/res/values-uz-watch/strings.xml b/PermissionController/res/values-uz-watch/strings.xml index dbc7ee1a5..9ac60d9bc 100644 --- a/PermissionController/res/values-uz-watch/strings.xml +++ b/PermissionController/res/values-uz-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"O‘zgartirilmaydi"</string> <string name="generic_yes" msgid="2489207724988649846">"Ha"</string> <string name="generic_cancel" msgid="2631708607129269698">"Bekor q-sh"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Doimo"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Ilova ishlatilayotganda"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Doimo"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Ilova ishlatilayotganda"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Doimo"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Ilova ishlatilayotganda"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Doimo"</string> </resources> diff --git a/PermissionController/res/values-uz/strings.xml b/PermissionController/res/values-uz/strings.xml index 706ec1a6c..bcf2ad38a 100644 --- a/PermissionController/res/values-uz/strings.xml +++ b/PermissionController/res/values-uz/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Barcha ruxsatlar"</string> <string name="other_permissions" msgid="2901186127193849594">"Ilovaning boshqa imkoniyatlari"</string> <string name="permission_request_title" msgid="8790310151025020126">"Ruxsat olish talabi"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear qurilmasi o‘rnatish/o‘chirish amallarini qo‘llab-quvvatlamaydi."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uchun beriladigan ruxsatlarni tanlang"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> yangilandi. Unga beriladigan ruxsatlarni tanlang."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Bekor qilish"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Aniq joylashuv yoqilmasa, ilovalar taxminiy joylashuvingiz axborotidan foydalanadi"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> ruxsati"</string> <string name="app_permission_header" msgid="2951363137032603806">"Bu ilova uchun <xliff:g id="PERM">%1$s</xliff:g> ruxsati"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>da bu ilova uchun <xliff:g id="PERM">%1$s</xliff:g> kirish ruxsati"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"<xliff:g id="APP">%1$s</xliff:g> uchun berilgan barcha ruxsatlar"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Bu ruxsatga ega barcha ilovalar"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Assistent uchun mikrofondan foydalanishni koʻrsatish"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Ishlatilmayotgan ilovalardan ruxsatlarni olib tashlash"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Ruxsatlarni olib tashlash va joy ochish"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Ishlatilmayotgan ilovalarni pauzalash"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Ishlatilmagan ilovalarni boshqarish"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Ruxsatlarni olib tashlash, vaqtinchalik fayllarni oʻchirish va bildirishnomalarni toʻxtatish"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Ruxsatlarni olib tashlash, vaqtinchalik fayllarni oʻchirish, bildirishnomalarni toʻxtatish va ilovani arxivlash"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Xavfsizlik yuzasidan, bir necha oydan beri ishlatilmagan ilovalardan ruxsatlar olib tashlanadi"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Agar bu ilova bir necha oy ishlatilmasa, quyidagi ruxsatlar olib tashlanadi: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Xavfsizlik yuzasidan, bir necha oydan beri ishlatilmagan ilovalardan ruxsatlar olib tashlanadi"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Barcha fayllarga ruxsati bor"</string> <string name="ask_header" msgid="2633816846459944376">"Har safar soʻralsin"</string> <string name="denied_header" msgid="903209608358177654">"Ruxsat berilmagan"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> — <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Barcha fayllarga kirish uchun koʻproq ilovalarni koʻring"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 kun}other{# kun}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# soat}other{# soat}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Qaydlar ilovasi"</string> <string name="role_notes_description" msgid="8496852798616883551">"Qurilmangizda qaydlar olish imkonini beruvchi ilovalar"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"qaydlar"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Birlamchi hamyon ilovasi"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Hamyon ilovasi"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Hamyon ilovalarda kredit va sodiqlik kartalari, avtomobil kalitlari hamda boshqa raqamli mahsulotlarni saqlash mumkin. Bu har xil turdagi amaliyotlarni bajarishni yanada qulaylashtiradi."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"<xliff:g id="APP_NAME">%1$s</xliff:g> birlamchi hamyon ilovasi sifatida belgilansinmi?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Hech qanday ruxsat zarur emas"</string> <string name="request_role_current_default" msgid="738722892438247184">"Hozirda asosiy ilova"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Boshqa soʻralmasin"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Birlamchi deb belgilash"</string> @@ -524,8 +531,8 @@ <string name="permgroupbackgroundrequestdetail_sensors" msgid="7726767635834043501">"Bu ilovaga tanadagi sensor maʼlumotlaridan foydalanishga (hatto ilova yopiqligida ham) doimiy ruxsat berish uchun "<annotation id="link">"sozlamalarni oching."</annotation></string> <string name="permgroupupgraderequest_sensors" msgid="7576527638411370468">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ilovasining tanadagi sensor maʼlumotlaridan foydalanishiga ruxsat berilsinmi?"</string> <string name="permgroupupgraderequest_device_aware_sensors" msgid="3310667992344623159">"<b><xliff:g id="DEVICE">%2$s</xliff:g></b>da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ilovasi tanadagi sensor maʼlumotlaridan foydalanishiga ruxsat berilaversinmi?"</string> - <string name="permgrouprequest_notifications" msgid="6396739062335106181">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ilovasiga sizga bildirishnomalar yuborishi uchun ruxsat berilsinmi?"</string> - <string name="permgrouprequest_device_aware_notifications" msgid="7307588961166360244">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ilovasiga <b><xliff:g id="DEVICE">%2$s</xliff:g></b>da sizga bildirishnomalar yuborishi uchun ruxsat berilsinmi?"</string> + <string name="permgrouprequest_notifications" msgid="6396739062335106181">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sizga bildirishnomalar yuborishi uchun ruxsat berilsinmi?"</string> + <string name="permgrouprequest_device_aware_notifications" msgid="7307588961166360244">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <b><xliff:g id="DEVICE">%2$s</xliff:g></b> qurilmasida sizga bildirishnomalar yuborishi uchun ruxsat berilsinmi?"</string> <string name="auto_granted_permissions" msgid="6009452264824455892">"Boshqariluvchi ruxsatlar"</string> <string name="auto_granted_location_permission_notification_title" msgid="7570818224669050377">"<xliff:g id="APP_NAME">%1$s</xliff:g> joylashuvga kira oladi"</string> <string name="auto_granted_permission_notification_body" msgid="5040234389205471318">"Tashkilotingiz <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga joylashuvingizga kirishga ruxsat bergan"</string> @@ -545,7 +552,7 @@ <string name="exempt_info_label" msgid="6286190981253476699">"<xliff:g id="APP_NAME">%1$s</xliff:g> Android tomonidan himoyalangan. Maʼlumotlaringiz qurilmada qayta ishlanishi sababli ilovaning ruxsatlardan foydalanish statistikasi maxfiylik boshqaruv panelida chiqmaydi."</string> <string name="blocked_camera_title" msgid="1128510551791284384">"Qurilma kamerasi bloklandi"</string> <string name="blocked_microphone_title" msgid="1631517143648232585">"Qurilma mikrofoni bloklandi"</string> - <string name="blocked_location_title" msgid="2005608279812892383">"Qurilmada joylashuv axboroti yoqilmagan"</string> + <string name="blocked_location_title" msgid="2005608279812892383">"Qurilmada joylashuvni aniqlash oʻchiq"</string> <string name="blocked_sensor_summary" msgid="4443707628305027375">"Ilovalar va xizmatlar uchun"</string> <string name="blocked_mic_summary" msgid="8960466941528458347">"Favqulodda xizmat raqamiga telefon qilganingizda mikrofon maʼlumotlari hamon ulashilishi mumkin."</string> <string name="blocked_sensor_button_label" msgid="6742092634984289658">"Oʻzgartirish"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Axborot ulashuvi yangilanishi"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Ayrim ilovalarda joylashuv axboroti ulashuvi oʻzgardi"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Sozlamalar"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Kirilgan: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Kecha kirilgan: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Kirilgan: <xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Bir martalik parolingiz: 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Cheklangan sozlama"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Xavfsizlik maqsadida bu sozlama hozir ishlamaydi."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Ilovaga <xliff:g id="PERMISSION_NAME">%1$s</xliff:g> ruxsati berilmadi"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Ilova maxfiy maʼlumotlarga kirish uchun ruxsat soʻramoqda. Ruxsat bersangiz, shaxsiy va moliyaviy maʼlumotlaringiz xavf ostida qolishi mumkin.<xliff:g id="ID_1"><br><br></xliff:g> Bu cheklangan ruxsatsiz ilova toʻgʻri ishlamasligi mumkin. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Qanday ruxsat berish haqida batafsil</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Ilovadan <xliff:g id="ROLE_NAME">%1$s</xliff:g> turkumidagi standart sifatida foydalanish taqiqlangan"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Ilova maxfiy maʼlumotlarga kirish uchun ruxsat soʻramoqda. Ruxsat bersangiz, shaxsiy va moliyaviy maʼlumotlaringiz xavf ostida qolishi mumkin.<xliff:g id="ID_1"><br><br></xliff:g> Bu cheklangan ruxsatlarsiz ilova toʻgʻri ishlamasligi mumkin. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Qanday ruxsat berish haqida batafsil</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Ilovaga ruxsat rad etildi"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Bu ruxsatdan foydalanish shaxsiy va moliyaviy axborotlaringizni xavf ostiga qoʻyishi mumkin.<xliff:g id="ID_1"><br><br></xliff:g>Bu cheklangan ruxsatsiz ilova toʻgʻri ishlamasligi mumkin. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Qanday ruxsat berish haqida batafsil</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Batafsil"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Ruxsat talabi bloklandi"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Bu ilova qoʻshimcha ruxsatlar talab qilmoqda, lekin ruxsatlar striming seansida berilmaydi. Avval telefoningizda ruxsat bering."</string> </resources> diff --git a/PermissionController/res/values-v33/styles.xml b/PermissionController/res/values-v33/styles.xml index e4d8f5c54..94344615b 100644 --- a/PermissionController/res/values-v33/styles.xml +++ b/PermissionController/res/values-v33/styles.xml @@ -566,6 +566,12 @@ <item name="android:background">@drawable/safety_center_more_issues_card_background</item> </style> + <style name="SafetyCenterMoreIssuesIcon" + parent="android:Widget.DeviceDefault"> + <item name="android:layout_height">20dp</item> + <item name="android:layout_width">20dp</item> + </style> + <style name="SafetyCenterMoreIssuesTitle" parent="SafetyCenterBaseTextContainer"> <item name="android:textAppearance">@style/TextAppearance.Material3.LabelLarge</item> @@ -576,43 +582,22 @@ <item name="android:layout_marginEnd">@dimen/sc_spacing_xxlarge</item> <item name="android:maxLines">2</item> <item name="android:ellipsize">end</item> - <item name="layout_constraintTop_toTopOf">parent</item> - <item name="layout_constraintBottom_toBottomOf">parent</item> - <item name="layout_constraintStart_toEndOf">@id/status_icon</item> - <item name="layout_constraintEnd_toStartOf">@android:id/widget_frame</item> <item name="layout_constraintHorizontal_bias">0</item> <item name="layout_goneMarginStart">0dp</item> </style> - <style name="SafetyCenterMoreIssuesIcon" - parent="android:Widget.DeviceDefault"> - <item name="android:layout_height">20dp</item> - <item name="android:layout_width">20dp</item> - <item name="android:gravity">center</item> - <item name="layout_constraintTop_toTopOf">parent</item> - <item name="layout_constraintBottom_toBottomOf">parent</item> - <item name="layout_constraintStart_toStartOf">parent</item> - </style> - <style name="SafetyCenterMoreIssuesCounter" parent="android:Widget.DeviceDefault"> - <item name="android:layout_height">24dp</item> - <item name="android:layout_width">wrap_content</item> - <item name="android:orientation">horizontal</item> - <item name="android:paddingStart">@dimen/sc_spacing_xsmall</item> - <item name="android:paddingEnd">@dimen/sc_spacing_xsmall</item> + <item name="android:layout_height">0dp</item> + <item name="android:layout_width">0dp</item> <item name="android:background">@drawable/safety_center_card_widget_background</item> - <item name="android:gravity">center_vertical</item> - <item name="layout_constraintTop_toTopOf">parent</item> - <item name="layout_constraintBottom_toBottomOf">parent</item> - <item name="layout_constraintEnd_toEndOf">parent</item> </style> <style name="SafetyCenterMoreIssuesWidgetTitle" parent="SafetyCenterBaseTextContainer"> <item name="android:textAppearance">@style/TextAppearance.SafetyCenter.Body</item> - <item name="android:lineHeight">@dimen/sc_line_height_medium</item> <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:paddingStart">@dimen/sc_spacing_xsmall</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_marginEnd">@dimen/sc_spacing_xxxsmall</item> @@ -623,8 +608,8 @@ parent="android:Widget.DeviceDefault"> <item name="android:layout_height">16dp</item> <item name="android:layout_width">16dp</item> - <item name="android:gravity">center</item> <item name="android:scaleType">fitCenter</item> + <item name="android:layout_marginEnd">@dimen/sc_spacing_xsmall</item> </style> <style name="SafetyCenterEntry" diff --git a/PermissionController/res/values-v34/strings.xml b/PermissionController/res/values-v34/strings.xml index 26a9b4bcc..a63586591 100644 --- a/PermissionController/res/values-v34/strings.xml +++ b/PermissionController/res/values-v34/strings.xml @@ -31,5 +31,4 @@ <!-- Describes what is affected by the mic toggle. Unlike the similar tc/9163104307990677157, there should NOT be a full stop at the end of this sentence. [CHAR LIMIT=NONE] --> <string name="mic_toggle_description">For apps and services. If this setting is off, microphone data may still be shared when you call an emergency number</string> <!-- Subtitle for the link to location settings [CHAR LIMIT=NONE] --> - <string name="location_settings_subtitle">For apps and services</string> </resources> diff --git a/PermissionController/res/values-v34/styles.xml b/PermissionController/res/values-v34/styles.xml index 53780ce76..6ba504531 100644 --- a/PermissionController/res/values-v34/styles.xml +++ b/PermissionController/res/values-v34/styles.xml @@ -370,5 +370,4 @@ </style> <!-- END SAFETY CENTER SUBPAGE --> - </resources>
\ No newline at end of file diff --git a/PermissionController/res/values-v35/themes.xml b/PermissionController/res/values-v35/themes.xml new file mode 100644 index 000000000..5785e5500 --- /dev/null +++ b/PermissionController/res/values-v35/themes.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<resources> + + <!-- + TODO(b/309578419): Make activities handle insets properly and then remove this. + --> + <style name="OptOutEdgeToEdgeEnforcement"> + <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item> + </style> + +</resources> diff --git a/PermissionController/res/values-vi-v34/strings.xml b/PermissionController/res/values-vi-v34/strings.xml index 618a266d8..836d98f28 100644 --- a/PermissionController/res/values-vi-v34/strings.xml +++ b/PermissionController/res/values-vi-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Quản lý quyền truy cập của ứng dụng vào dữ liệu sức khoẻ"</string> <string name="location_settings" msgid="8863940440881290182">"Quyền truy cập thông tin vị trí"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Áp dụng cho các ứng dụng và dịch vụ. Nếu bạn tắt chế độ cài đặt này, dữ liệu thu được qua micrô vẫn có thể được chia sẻ khi bạn gọi đến số khẩn cấp"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Áp dụng cho các ứng dụng và dịch vụ"</string> </resources> diff --git a/PermissionController/res/values-vi-watch/strings.xml b/PermissionController/res/values-vi-watch/strings.xml index 21054e6d4..21ff1bd5c 100644 --- a/PermissionController/res/values-vi-watch/strings.xml +++ b/PermissionController/res/values-vi-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Không thể thay đổi"</string> <string name="generic_yes" msgid="2489207724988649846">"Có"</string> <string name="generic_cancel" msgid="2631708607129269698">"Hủy"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Mọi lúc"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Khi dùng ứng dụng"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Mọi lúc"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Khi dùng ứng dụng"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Mọi lúc"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Khi dùng ứng dụng"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Mọi lúc"</string> </resources> diff --git a/PermissionController/res/values-vi/strings.xml b/PermissionController/res/values-vi/strings.xml index 72275f442..3015ce90c 100644 --- a/PermissionController/res/values-vi/strings.xml +++ b/PermissionController/res/values-vi/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Tất cả các quyền"</string> <string name="other_permissions" msgid="2901186127193849594">"Các khả năng khác của ứng dụng"</string> <string name="permission_request_title" msgid="8790310151025020126">"Yêu cầu quyền"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Các hành động Cài đặt/Gỡ cài đặt không được hỗ trợ trên Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Chọn nội dung <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> được phép truy cập vào"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"Đã cập nhật <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Chọn nội dung ứng dụng này được phép truy cập vào."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Hủy"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Khi chế độ vị trí chính xác đang tắt, các ứng dụng có thể truy cập vào thông tin vị trí gần đúng của bạn"</string> <string name="app_permission_title" msgid="2090897901051370711">"Quyền <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Quyền truy cập <xliff:g id="PERM">%1$s</xliff:g> cho ứng dụng này"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Quyền truy cập <xliff:g id="PERM">%1$s</xliff:g> cho ứng dụng này trên <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Xem tất cả các quyền của <xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Xem tất cả ứng dụng có quyền này"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Hiển thị việc sử dụng micrô của Trợ lý"</string> <string name="unused_apps_category_title" msgid="2988455616845243901">"Chế độ cài đặt cho ứng dụng không dùng đến"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"Thu hồi quyền nếu bạn không dùng ứng dụng"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Thu hồi quyền và giải phóng dung lượng"</string> - <string name="unused_apps_label_v2" msgid="7058776770056517980">"Tạm dừng hoạt động trong ứng dụng nếu không dùng"</string> + <string name="unused_apps_label_v2" msgid="7058776770056517980">"Tạm dừng hoạt động của ứng dụng nếu không dùng"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Quản lý ứng dụng nếu không dùng"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Loại bỏ quyền, xoá tệp tạm thời và dừng thông báo"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Loại bỏ quyền, xoá tệp tạm thời, dừng thông báo và lưu trữ ứng dụng"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Để bảo vệ dữ liệu của bạn, các quyền cấp cho ứng dụng này sẽ bị thu hồi nếu bạn không dùng ứng dụng trong vài tháng."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Để bảo vệ dữ liệu của bạn, nếu bạn không dùng ứng dụng này trong vài tháng thì các quyền sau đây sẽ bị thu hồi: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Để bảo vệ dữ liệu của bạn, quản trị viên CNTT đã thu hồi các quyền đối với những ứng dụng bạn không dùng trong vài tháng."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Được phép quản lý tất cả các tệp"</string> <string name="ask_header" msgid="2633816846459944376">"Luôn hỏi"</string> <string name="denied_header" msgid="903209608358177654">"Không được phép"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> trên <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Xem thêm ứng dụng có thể truy cập tất cả các tệp"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 ngày}other{# ngày}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# giờ}other{# giờ}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"Ứng dụng ghi chú"</string> <string name="role_notes_description" msgid="8496852798616883551">"Các ứng dụng cho phép bạn tạo ghi chú trên thiết bị"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"ghi chú"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"Ứng dụng ví mặc định"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"Ứng dụng ví"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Ứng dụng ví có thể lưu trữ thông tin thẻ tín dụng và thẻ khách hàng thân thiết của bạn, chìa khoá ô tô của bạn, cùng nhiều thông tin khác giúp bạn thực hiện nhiều hình thức giao dịch đa dạng."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Đặt <xliff:g id="APP_NAME">%1$s</xliff:g> làm ứng dụng ví mặc định?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Không cần quyền"</string> <string name="request_role_current_default" msgid="738722892438247184">"Ứng dụng mặc định hiện tại"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Không hỏi lại"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Đặt làm mặc định"</string> @@ -564,7 +571,7 @@ <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Kiểm tra trạng thái"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Các chế độ kiểm soát quyền riêng tư"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"Tùy chọn cài đặt khác"</string> - <string name="camera_toggle_label_qs" msgid="3880261453066157285">"Quyền truy cập máy ảnh"</string> + <string name="camera_toggle_label_qs" msgid="3880261453066157285">"Quyền truy cập camera"</string> <string name="microphone_toggle_label_qs" msgid="8132912469813396552">"Quyền truy cập micrô"</string> <string name="permissions_removed_qs" msgid="8957319130625294572">"Đã thu hồi quyền sử dụng"</string> <string name="camera_usage_qs" msgid="4394233566086665994">"Xem mức sử dụng của máy ảnh gần đây"</string> @@ -606,7 +613,7 @@ <string name="safety_center_background_location_access_revoked" msgid="6972274943343442213">"Đã thay đổi quyền truy cập"</string> <string name="safety_center_view_recent_location_access" msgid="3524391299490678243">"Xem thông tin về hoạt động sử dụng thông tin vị trí gần đây"</string> <string name="privacy_controls_title" msgid="7605929972256835199">"Chế độ kiểm soát quyền riêng tư"</string> - <string name="camera_toggle_title" msgid="1251201397431837666">"Quyền truy cập máy ảnh"</string> + <string name="camera_toggle_title" msgid="1251201397431837666">"Quyền truy cập camera"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"Quyền truy cập micrô"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"Áp dụng cho các ứng dụng và dịch vụ"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"Áp dụng cho các ứng dụng và dịch vụ. Nếu bạn tắt chế độ cài đặt, dữ liệu thu được qua micrô vẫn có thể được chia sẻ khi bạn gọi đến số khẩn cấp."</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Nội dung cập nhật về cách thức chia sẻ dữ liệu"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Một số ứng dụng đã thay đổi cách thức có thể được dùng để chia sẻ dữ liệu vị trí của bạn"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Cài đặt"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Truy cập lúc <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Truy cập hôm qua lúc <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Truy cập lúc <xliff:g id="TIME_DATE_1">%2$s</xliff:g> ngày <xliff:g id="TIME_DATE_0">%1$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Mật khẩu một lần của bạn là 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Chế độ cài đặt bị hạn chế"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Để đảm bảo an toàn cho bạn, chế độ cài đặt này hiện không dùng được."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Ứng dụng đã bị từ chối cấp quyền truy cập vào <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Ứng dụng này yêu cầu quyền truy cập vào thông tin nhạy cảm. Việc đó có thể khiến thông tin cá nhân và thông tin tài chính của bạn gặp rủi ro.<xliff:g id="ID_1"><br><br></xliff:g>Có thể ứng dụng sẽ hoạt động không đúng cách nếu không được cấp quyền bị hạn chế này. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Tìm hiểu cách cấp quyền</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Ứng dụng đã bị từ chối cấp quyền để làm <xliff:g id="ROLE_NAME">%1$s</xliff:g> mặc định"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"Ứng dụng này yêu cầu quyền truy cập vào thông tin nhạy cảm. Việc đó có thể khiến thông tin cá nhân và thông tin tài chính của bạn gặp rủi ro.<xliff:g id="ID_1"><br><br></xliff:g>Có thể ứng dụng sẽ hoạt động không đúng cách nếu không được cấp quyền bị hạn chế này. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Tìm hiểu cách cấp quyền</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"Ứng dụng đã bị từ chối cấp quyền"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Việc cấp quyền này có thể khiến thông tin cá nhân và thông tin tài chính của bạn gặp rủi ro.<xliff:g id="ID_1"><br><br></xliff:g>Có thể ứng dụng sẽ hoạt động không đúng cách nếu không được cấp quyền bị hạn chế này. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Tìm hiểu cách cấp quyền</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Tìm hiểu thêm"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"OK"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Yêu cầu quyền đã bị chặn"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Ứng dụng này đang yêu cầu thêm quyền, nhưng bạn không thể cấp quyền trong một phiên truyền trực tuyến. Trước tiên, hãy cấp quyền trên điện thoại của bạn."</string> </resources> diff --git a/PermissionController/res/values-watch/donottranslate.xml b/PermissionController/res/values-watch/donottranslate.xml new file mode 100644 index 000000000..c3ab3cbb1 --- /dev/null +++ b/PermissionController/res/values-watch/donottranslate.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- font-family-device-default is expected to be preloaded in the font_customization.xml(/vendor/<OEM>/products/<PRODUCT>/fonts/fonts_customization.xml)--> + <!-- Falls back to system default when font-family-device-default doesn't exist --> + <string name="wear_material_compose_display_1_font_family">font-family-device-default</string> + <string name="wear_material_compose_display_2_font_family">font-family-device-default</string> + <string name="wear_material_compose_display_3_font_family">font-family-device-default</string> + <string name="wear_material_compose_title_1_font_family">font-family-medium-device-default</string> + <string name="wear_material_compose_title_2_font_family">font-family-medium-device-default</string> + <string name="wear_material_compose_title_3_font_family">font-family-device-default</string> + <string name="wear_material_compose_body_1_font_family">font-family-text-device-default</string> + <string name="wear_material_compose_body_2_font_family">font-family-text-device-default</string> + <string name="wear_material_compose_button_font_family">font-family-text-medium-device-default</string> + <string name="wear_material_compose_caption_1_font_family">font-family-text-medium-device-default</string> + <string name="wear_material_compose_caption_2_font_family">font-family-text-medium-device-default</string> + <string name="wear_material_compose_caption_3_font_family">font-family-text-medium-device-default</string> +</resources> diff --git a/PermissionController/res/values-watch/strings.xml b/PermissionController/res/values-watch/strings.xml index f940eae65..60aca8fe9 100644 --- a/PermissionController/res/values-watch/strings.xml +++ b/PermissionController/res/values-watch/strings.xml @@ -35,4 +35,25 @@ <!-- Generic text to indicate Cancel. [CHAR LIMIT=10] --> <string name="generic_cancel">Cancel</string> + + <!-- [CHAR LIMIT=25] App can always (when app is in foreground or background) access the resource protected by the permission --> + <string name="permission_access_always">All the time</string> + + <!-- App can only access the resource protected by the permission while app is in foreground [CHAR LIMIT=25]--> + <string name="permission_access_only_foreground">While using app</string> + + <!-- Title for the dialog button to allow a permission grant when you can also only allow in the foreground. [CHAR LIMIT=25] --> + <string name="app_permission_button_allow_always">All the time</string> + + <!-- Title for the dialog button to allow a permission grant only when the app is in the foreground. [CHAR LIMIT=25] --> + <string name="app_permission_button_allow_foreground">While using app</string> + + <!-- Title for the dialog button to allow a permission grant when you can also only allow in the foreground. [CHAR LIMIT=25] --> + <string name="grant_dialog_button_allow_always">All the time</string> + + <!-- Title for the dialog button to allow a permission grant only when the app is in the foreground. [CHAR LIMIT=25] --> + <string name="grant_dialog_button_allow_foreground">While using app</string> + + <!-- Title for the dialog button to allow a change from foreground to background permission grant. [CHAR LIMIT=25] --> + <string name="grant_dialog_button_allow_background">All the time</string> </resources> diff --git a/PermissionController/res/values-zh-rCN-v34/strings.xml b/PermissionController/res/values-zh-rCN-v34/strings.xml index 0ba05798b..fbb8bc6db 100644 --- a/PermissionController/res/values-zh-rCN-v34/strings.xml +++ b/PermissionController/res/values-zh-rCN-v34/strings.xml @@ -19,9 +19,8 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="security_privacy_brand_name" msgid="7303621734258440812">"安全和隐私"</string> <string name="privacy_subpage_controls_header" msgid="4152396976713749322">"控件"</string> - <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> + <string name="health_connect_title" msgid="2132233890867430855">"健康数据共享"</string> <string name="health_connect_summary" msgid="815473513776882296">"管理应用对健康数据的访问权限"</string> <string name="location_settings" msgid="8863940440881290182">"位置信息访问权限"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"针对应用和服务。关闭此设置后,系统仍可能在您拨打紧急电话号码时分享麦克风数据"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"针对应用和服务"</string> </resources> diff --git a/PermissionController/res/values-zh-rCN-watch/strings.xml b/PermissionController/res/values-zh-rCN-watch/strings.xml index 67671132f..b8860dfbb 100644 --- a/PermissionController/res/values-zh-rCN-watch/strings.xml +++ b/PermissionController/res/values-zh-rCN-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"无法更改"</string> <string name="generic_yes" msgid="2489207724988649846">"是"</string> <string name="generic_cancel" msgid="2631708607129269698">"取消"</string> + <string name="permission_access_always" msgid="2107115233573823032">"始终"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"在使用应用时"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"始终"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"在使用应用时"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"始终"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"在使用应用时"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"始终"</string> </resources> diff --git a/PermissionController/res/values-zh-rCN/strings.xml b/PermissionController/res/values-zh-rCN/strings.xml index 985bd4fc7..205ee8a50 100644 --- a/PermissionController/res/values-zh-rCN/strings.xml +++ b/PermissionController/res/values-zh-rCN/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"所有权限"</string> <string name="other_permissions" msgid="2901186127193849594">"其他应用功能"</string> <string name="permission_request_title" msgid="8790310151025020126">"权限请求"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear 不支持安装/卸载操作。"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"请选择要向<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>授予哪些权限"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>已更新。请选择要向此应用授予哪些权限。"</string> <string name="review_button_cancel" msgid="2191147944056548886">"取消"</string> @@ -199,6 +197,7 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"确切位置关闭时,应用可以获取您的大致位置"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>权限"</string> <string name="app_permission_header" msgid="2951363137032603806">"是否允许此应用获得“<xliff:g id="PERM">%1$s</xliff:g>”权限"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"此应用在<xliff:g id="DEVICE_NAME">%2$s</xliff:g>上的<xliff:g id="PERM">%1$s</xliff:g>访问权限"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"查看“<xliff:g id="APP">%1$s</xliff:g>”的所有权限"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"查看具有此权限的所有应用"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"显示 Google 助理麦克风使用情况"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"如果未使用此应用,则移除相关权限"</string> <string name="unused_apps_label" msgid="2595428768404901064">"撤消权限并释放空间"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"暂停闲置应用的活动"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"管理闲置应用"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"移除权限、删除临时文件并停止发送通知"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"撤消权限、删除临时文件、停止发送通知并归档应用"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"为了保护您的数据,如果您连续几个月未使用此应用,系统会移除它的权限。"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"为了保护您的数据,如果您连续几个月未使用此应用,系统会移除其以下权限:<xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"为了保护您的数据,对于您连续几个月未使用过的应用,系统已将其权限移除。"</string> @@ -234,7 +235,7 @@ <string name="permission_description_summary_call_log" msgid="7321437186317577624">"具有此权限的应用可以读取和写入手机通话记录"</string> <string name="permission_description_summary_camera" msgid="108004375101882069">"具有此权限的应用可以拍摄照片和录制视频"</string> <string name="permission_description_summary_contacts" msgid="2337798886460408996">"具有此权限的应用可以访问您的通讯录"</string> - <string name="permission_description_summary_location" msgid="2817531799933480694">"具有此权限的应用可以使用此设备的位置信息"</string> + <string name="permission_description_summary_location" msgid="2817531799933480694">"具有此权限的应用可以访问此设备的位置信息"</string> <string name="permission_description_summary_nearby_devices" msgid="8269183818275073741">"具有这项权限的应用可以查找、连接附近设备,以及确定附近设备的相对位置"</string> <string name="permission_description_summary_microphone" msgid="630834800308329907">"具有此权限的应用可以录制音频"</string> <string name="permission_description_summary_phone" msgid="4515277217435233619">"具有此权限的应用可以拨打电话及管理通话"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"获准管理所有文件"</string> <string name="ask_header" msgid="2633816846459944376">"每次都询问"</string> <string name="denied_header" msgid="903209608358177654">"不允许"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>上的<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"查看更多可以访问所有文件的应用"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 天}other{# 天}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# 小时}other{# 小时}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"记事应用"</string> <string name="role_notes_description" msgid="8496852798616883551">"允许您在设备上记事的应用"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"记事"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"默认钱包应用"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"钱包应用"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"钱包应用可以存储信用卡和会员卡、车钥匙和其他内容,帮助您完成各种形式的交易。"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"要将“<xliff:g id="APP_NAME">%1$s</xliff:g>”设为默认钱包应用?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"无需任何权限"</string> <string name="request_role_current_default" msgid="738722892438247184">"当前默认应用"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"不再询问"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"设为默认应用"</string> @@ -636,8 +643,8 @@ <string name="app_permission_rationale_message" msgid="8511466916077100713">"数据安全"</string> <string name="app_location_permission_rationale_title" msgid="925420340572401350">"可能会分享位置数据"</string> <string name="app_location_permission_rationale_subtitle" msgid="6986985722752868692">"此应用已声明它可能会与第三方分享您的位置数据"</string> - <string name="data_sharing_updates_title" msgid="7996933386875213859">"位置数据分享方面的更新"</string> - <string name="data_sharing_updates_summary" msgid="764113985772233889">"查看改变了位置数据分享方式的应用"</string> + <string name="data_sharing_updates_title" msgid="7996933386875213859">"位置数据共享方面的更新"</string> + <string name="data_sharing_updates_summary" msgid="764113985772233889">"查看改变了位置数据共享方式的应用"</string> <string name="data_sharing_updates_subtitle" msgid="6311537708950632329">"这些应用改变了它们在分享您位置数据上的做法。它们之前可能未分享过位置数据,也可能现在是为了广告或营销目的而分享此类数据。"</string> <string name="data_sharing_updates_footer_message" msgid="1582711655172892107">"这些应用的开发者已将其数据分享做法相关信息提供给应用商店。此类信息可能会随时间更新。\n\n数据分享做法可能会因应用版本、使用情况、地区和年龄而异。"</string> <string name="learn_about_data_sharing" msgid="4200480587079488045">"了解数据分享"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"数据分享方式变更"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"部分应用更改了位置数据分享方式"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"设置"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"<xliff:g id="TIME_DATE">%1$s</xliff:g>访问过"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"昨天<xliff:g id="TIME_DATE">%1$s</xliff:g>访问过"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"<xliff:g id="TIME_DATE_0">%1$s</xliff:g><xliff:g id="TIME_DATE_1">%2$s</xliff:g>访问过"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"您的动态密码为 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"受限制的设置"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"出于安全考虑,此设置目前不可用。"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"系统已拒绝向此应用授予<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>访问权限"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"该应用请求获得敏感权限,授予这项权限可能会导致您的个人信息和财务信息面临风险。<xliff:g id="ID_1"><br><br></xliff:g>如果不授予这项受限权限,该应用可能无法正常工作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>了解如何授予访问权限</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"系统已拒绝向此应用授予作为默认<xliff:g id="ROLE_NAME">%1$s</xliff:g>的访问权限"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"该应用请求获得敏感权限,授予这项权限可能会导致您的个人信息和财务信息面临风险。<xliff:g id="ID_1"><br><br></xliff:g>如果不授予这些受限权限,该应用可能无法正常工作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>了解如何授予访问权限</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"系统已拒绝向此应用授予访问权限"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"如果授予此权限,您的个人信息和财务信息可能会面临风险。<xliff:g id="ID_1"><br><br></xliff:g>如果不授予这项受限权限,该应用可能无法正常工作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>了解如何授予访问权限</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"了解详情"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"确定"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"权限请求被阻止"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"此应用请求获得额外的权限,但在流式传输会话期间无法授予权限。请先在手机上授予相应权限。"</string> </resources> diff --git a/PermissionController/res/values-zh-rHK-v34/strings.xml b/PermissionController/res/values-zh-rHK-v34/strings.xml index 65ad05bdb..5414ff55f 100644 --- a/PermissionController/res/values-zh-rHK-v34/strings.xml +++ b/PermissionController/res/values-zh-rHK-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"管理應用程式的健康資料存取權"</string> <string name="location_settings" msgid="8863940440881290182">"位置資料存取權"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"適用於應用程式和服務。如果關閉此設定,系統仍會在你撥打緊急電話號碼時提供麥克風的資料"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"應用程式和服務"</string> </resources> diff --git a/PermissionController/res/values-zh-rHK-watch/strings.xml b/PermissionController/res/values-zh-rHK-watch/strings.xml index abe2f31f9..01f23b65c 100644 --- a/PermissionController/res/values-zh-rHK-watch/strings.xml +++ b/PermissionController/res/values-zh-rHK-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"不可變更"</string> <string name="generic_yes" msgid="2489207724988649846">"是"</string> <string name="generic_cancel" msgid="2631708607129269698">"取消"</string> + <string name="permission_access_always" msgid="2107115233573823032">"一律允許"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"使用應用程式時"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"一律允許"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"使用應用程式時"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"一律允許"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"使用應用程式時"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"一律允許"</string> </resources> diff --git a/PermissionController/res/values-zh-rHK/strings.xml b/PermissionController/res/values-zh-rHK/strings.xml index 4bb7a8338..b13341e35 100644 --- a/PermissionController/res/values-zh-rHK/strings.xml +++ b/PermissionController/res/values-zh-rHK/strings.xml @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"所有權限"</string> <string name="other_permissions" msgid="2901186127193849594">"其他應用程式功能"</string> <string name="permission_request_title" msgid="8790310151025020126">"權限要求"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear 不支援安裝/解除安裝操作。"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"選擇允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取的內容"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"已更新「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>。選擇允許此應用程式存取的內容。"</string> <string name="review_button_cancel" msgid="2191147944056548886">"取消"</string> @@ -199,14 +197,17 @@ <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"關閉精確位置後,應用程式可存取你的概略位置"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>權限"</string> <string name="app_permission_header" msgid="2951363137032603806">"這個應用程式的<xliff:g id="PERM">%1$s</xliff:g>存取權"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"此應用程式在<xliff:g id="DEVICE_NAME">%2$s</xliff:g>上的<xliff:g id="PERM">%1$s</xliff:g>存取權"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"查看「<xliff:g id="APP">%1$s</xliff:g>」的所有權限"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"查看擁有此權限的所有應用程式"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"顯示「Google 助理」麥克風使用情況"</string> - <string name="unused_apps_category_title" msgid="2988455616845243901">"未使用的應用程式設定"</string> + <string name="unused_apps_category_title" msgid="2988455616845243901">"不使用的應用程式設定"</string> <string name="auto_revoke_label" msgid="5068393642936571656">"如不使用應用程式,即移除權限"</string> <string name="unused_apps_label" msgid="2595428768404901064">"移除權限並騰出空間"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"暫停未使用應用程式的活動"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"管理應用程式 (如未使用)"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"移除權限、刪除暫存檔案和停止通知"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"移除權限、刪除暫存檔案、停止通知和封存應用程式"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"為保護你的資料,系統已移除你在過去幾個月未曾使用的應用程式的權限。"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"為保護你的資料,如果應用程式在過去幾個月未曾使用,系統將會移除以下權限:<xliff:g id="PERMS">%1$s</xliff:g>。"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"為保護你的資料,系統已移除你在過去幾個月未曾使用的應用程式的權限。"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"允許管理所有檔案"</string> <string name="ask_header" msgid="2633816846459944376">"每次都詢問"</string> <string name="denied_header" msgid="903209608358177654">"不允許"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>上的<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"顯示更多可存取所有檔案的應用程式"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 天}other{# 天}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# 小時}other{# 小時}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"筆記應用程式"</string> <string name="role_notes_description" msgid="8496852798616883551">"讓你可以在裝置上寫筆記的應用程式"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"筆記"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"預設錢包應用程式"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"錢包應用程式"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"錢包應用程式可存放信用卡、會員卡、車匙和其他資料,助你完成各種形式的交易。"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"要將「<xliff:g id="APP_NAME">%1$s</xliff:g>」設定為預設錢包應用程式嗎?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"無需任何權限"</string> <string name="request_role_current_default" msgid="738722892438247184">"目前預設"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"不要再詢問"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"設定為預設"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取你的聯絡人嗎?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取你<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上的通訊錄嗎?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取此裝置的位置資訊嗎?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取你的<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>位置嗎?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"允許「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」存取<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>的位置嗎?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"此應用程式目前只有你在使用時才能存取位置資訊"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取此裝置的位置資訊嗎?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取你的<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>位置嗎?"</string> @@ -488,7 +495,7 @@ <string name="permgrouprequest_storage_pre_q" msgid="168130651144569428">"要允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取此裝置上的<b>相片、影片、音樂、音訊和其他檔案</b>嗎?"</string> <string name="permgrouprequest_read_media_aural" msgid="2593365397347577812">"要允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取此裝置上的音樂和音訊嗎?"</string> <string name="permgrouprequest_device_aware_read_media_aural" msgid="3331524384339036668">"允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取你<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上的音樂和音訊嗎?"</string> - <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"要允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取此裝置上的相片和影片嗎?"</string> + <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取此裝置上的相片和影片嗎?"</string> <string name="permgrouprequest_device_aware_read_media_visual" msgid="5492319750632751551">"允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取你<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上的相片和影片嗎?"</string> <string name="permgrouprequest_more_photos" msgid="128933814654231321">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取此裝置上更多的相片和影片?"</string> <string name="permgrouprequest_device_aware_more_photos" msgid="8946782319103584021">"允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 存取你<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上的相片和影片嗎?"</string> @@ -524,7 +531,7 @@ <string name="permgroupbackgroundrequestdetail_sensors" msgid="7726767635834043501">"如要讓此應用程式隨時存取人體感應器資料 (即使在你沒有使用此應用程式時),請"<annotation id="link">"前往設定"</annotation>"。"</string> <string name="permgroupupgraderequest_sensors" msgid="7576527638411370468">"要讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」應用程式<b></b>在使用時存取人體感應器資料嗎?"</string> <string name="permgroupupgraderequest_device_aware_sensors" msgid="3310667992344623159">"要繼續允許<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>在應用程式使用期間存取<b><xliff:g id="DEVICE">%2$s</xliff:g></b>的人體感應器資料嗎?"</string> - <string name="permgrouprequest_notifications" msgid="6396739062335106181">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>傳送通知給你嗎?"</string> + <string name="permgrouprequest_notifications" msgid="6396739062335106181">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>傳送通知給你嗎?"</string> <string name="permgrouprequest_device_aware_notifications" msgid="7307588961166360244">"允許 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 在你的<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上傳送通知給你嗎?"</string> <string name="auto_granted_permissions" msgid="6009452264824455892">"由管理員控制的權限"</string> <string name="auto_granted_location_permission_notification_title" msgid="7570818224669050377">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」有位置存取權"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"資料分享更新"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"部分應用程式已變更位置資料分享方式"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"設定"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"上次存取時間:<xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"上次存取時間:昨天<xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"上次存取時間:<xliff:g id="TIME_DATE_0">%1$s</xliff:g><xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"你的一次性密碼是 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"受限設定"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"為安全起見,系統目前不提供此設定。"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"系統已拒絕授予應用程式「<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>」存取權"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"應用程式要求存取敏感資料權限,授予此權限可能會危害你的個人和財務資料。<xliff:g id="ID_1"><br><br></xliff:g>如沒有此受限制權限,應用程式可能無法正常運作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>進一步瞭解如何授予存取權</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"系統已拒絕授予應用程式預設<xliff:g id="ROLE_NAME">%1$s</xliff:g>存取權"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"應用程式要求存取敏感資料權限,授予此權限可能會危害你的個人和財務資料。<xliff:g id="ID_1"><br><br></xliff:g>如沒有此受限制權限,應用程式可能無法正常運作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>進一步瞭解如何授予存取權</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"系統已拒絕授予應用程式存取權"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"授予此權限可能會危害你的個人和財務資料。<xliff:g id="ID_1"><br><br></xliff:g>如沒有此受限制權限,應用程式可能無法正常運作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>進一步瞭解如何授予存取權</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"瞭解詳情"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"確定"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"權限要求被拒"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"此應用程式要求額外的權限,但串流工作階段期間無法授予權限。請先在手機上授予權限。"</string> </resources> diff --git a/PermissionController/res/values-zh-rTW-v34/strings.xml b/PermissionController/res/values-zh-rTW-v34/strings.xml index e473ca41b..cebdecbaa 100644 --- a/PermissionController/res/values-zh-rTW-v34/strings.xml +++ b/PermissionController/res/values-zh-rTW-v34/strings.xml @@ -19,9 +19,8 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="security_privacy_brand_name" msgid="7303621734258440812">"安全性與隱私權"</string> <string name="privacy_subpage_controls_header" msgid="4152396976713749322">"控制選項"</string> - <string name="health_connect_title" msgid="2132233890867430855">"Health Connect"</string> + <string name="health_connect_title" msgid="2132233890867430855">"健康資料同步"</string> <string name="health_connect_summary" msgid="815473513776882296">"管理應用程式的健康資料存取權"</string> <string name="location_settings" msgid="8863940440881290182">"位置資訊存取權"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"適用於應用程式和服務。即使關閉這項設定,系統仍可能會在你撥打緊急電話號碼時,分享麥克風資料"</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"應用程式和服務"</string> </resources> diff --git a/PermissionController/res/values-zh-rTW-watch/strings.xml b/PermissionController/res/values-zh-rTW-watch/strings.xml index 2a91aa040..8173cc23f 100644 --- a/PermissionController/res/values-zh-rTW-watch/strings.xml +++ b/PermissionController/res/values-zh-rTW-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"無法變更"</string> <string name="generic_yes" msgid="2489207724988649846">"是"</string> <string name="generic_cancel" msgid="2631708607129269698">"取消"</string> + <string name="permission_access_always" msgid="2107115233573823032">"一律允許"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"僅限使用應用程式時"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"一律允許"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"僅限使用應用程式時"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"一律允許"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"僅限使用應用程式時"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"一律允許"</string> </resources> diff --git a/PermissionController/res/values-zh-rTW/strings.xml b/PermissionController/res/values-zh-rTW/strings.xml index c303926c1..0876dc770 100644 --- a/PermissionController/res/values-zh-rTW/strings.xml +++ b/PermissionController/res/values-zh-rTW/strings.xml @@ -53,7 +53,7 @@ <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"一律允許"</string> <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"使用應用程式時"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"改用精確位置"</string> - <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"繼續使用概略位置"</string> + <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"繼續使用大概位置"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"僅允許這一次"</string> <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"一律允許"</string> <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"允許管理所有檔案"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"所有權限"</string> <string name="other_permissions" msgid="2901186127193849594">"其他應用程式功能"</string> <string name="permission_request_title" msgid="8790310151025020126">"權限要求"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Wear 不支援安裝及解除安裝操作。"</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"選擇要授予「<xliff:g id="APP_NAME">%1$s</xliff:g>」的存取權"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已更新。請選擇要授予這個應用程式的存取權。"</string> <string name="review_button_cancel" msgid="2191147944056548886">"取消"</string> @@ -194,11 +192,12 @@ <string name="app_permission_button_ask" msgid="3342950658789427">"每次都詢問"</string> <string name="app_permission_button_deny" msgid="6016454069832050300">"不允許"</string> <string name="precise_image_description" msgid="6349638632303619872">"精確位置"</string> - <string name="approximate_image_description" msgid="938803699637069884">"概略位置"</string> + <string name="approximate_image_description" msgid="938803699637069884">"大概位置"</string> <string name="app_permission_location_accuracy" msgid="7166912915040018669">"使用精確位置"</string> - <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"精確位置關閉時,應用程式會存取你的概略位置資訊"</string> + <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"精確位置關閉時,應用程式會存取你的大概位置資訊"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g>權限"</string> <string name="app_permission_header" msgid="2951363137032603806">"是否允許這個應用程式取得「<xliff:g id="PERM">%1$s</xliff:g>」的存取權限"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"這個應用程式在<xliff:g id="DEVICE_NAME">%2$s</xliff:g>上的<xliff:g id="PERM">%1$s</xliff:g>存取權"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"查看「<xliff:g id="APP">%1$s</xliff:g>」的所有權限"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"查看具備此權限的所有應用程式"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"顯示 Google 助理的麥克風使用狀況"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"如果應用程式未使用,讓系統移除相關權限"</string> <string name="unused_apps_label" msgid="2595428768404901064">"移除權限並釋出空間"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"暫停未使用的應用程式活動"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"管理應用程式 (如未使用)"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"移除權限、刪除暫存檔及停止通知"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"移除權限、刪除暫存檔、停止通知並封存應用程式"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"為了保護你的資料,如果你連續幾個月都未使用這個應用程式,系統會移除其權限。"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"為了保護你的資料,如果應用程式已有數個月未使用,系統將移除以下權限:<xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"為了保護你的資料,針對數個月未使用的應用程式,系統已移除相關權限。"</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"可管理所有檔案"</string> <string name="ask_header" msgid="2633816846459944376">"每次都詢問"</string> <string name="denied_header" msgid="903209608358177654">"不允許"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>上的<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"查看可存取所有檔案的其他應用程式"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{1 天}other{# 天}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{# 小時}other{# 小時}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"記事應用程式"</string> <string name="role_notes_description" msgid="8496852798616883551">"可在裝置上記事的應用程式"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"記事"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"預設錢包應用程式"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"錢包應用程式"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"錢包應用程式可存放消費金、會員卡、車鑰和其他資訊,幫助完成各種形式的交易。"</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"要將「<xliff:g id="APP_NAME">%1$s</xliff:g>」設為預設錢包應用程式嗎?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"無需任何權限"</string> <string name="request_role_current_default" msgid="738722892438247184">"目前的預設應用程式"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"不要再詢問"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"設為預設"</string> @@ -461,7 +468,7 @@ <string name="permgrouprequest_contacts" msgid="8391550064551053695">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取你的聯絡人嗎?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="2270563860206654757">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>在<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上存取你的聯絡人嗎?"</string> <string name="permgrouprequest_location" msgid="6990232580121067883">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取這部裝置的位置資訊嗎?"</string> - <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b>的位置資訊嗎?"</string> + <string name="permgrouprequest_device_aware_location" msgid="6641436550953715107">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取<b> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> </b>的位置資訊嗎?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"該應用程式只有在你使用時,才能存取位置資訊"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取這部裝置的位置資訊嗎?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="7660465507029650527">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>的位置資訊嗎?"</string> @@ -472,12 +479,12 @@ <string name="permgrouprequest_nearby_devices" msgid="2272829282660436700">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>尋找、連結及判斷附近裝置的相對位置嗎?"</string> <string name="permgrouprequest_device_aware_nearby_devices" msgid="7919687165848885665">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>在<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上尋找鄰近裝置、與其連線並判斷相對位置嗎?"</string> <string name="permgroupupgraderequestdetail_nearby_devices" msgid="6877531270654738614">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>尋找、連結及判斷附近裝置的相對位置嗎?"<annotation id="link">"請前往「設定」授予權限。"</annotation></string> - <string name="permgrouprequest_fineupgrade" msgid="2334242928821697672">"要將「<xliff:g id="APP_NAME"><b>%1$s</b></xliff:g>」可以存取的定位資訊從「概略位置」改為「精確位置」嗎?"</string> + <string name="permgrouprequest_fineupgrade" msgid="2334242928821697672">"要將「<xliff:g id="APP_NAME"><b>%1$s</b></xliff:g>」可以存取的定位資訊從「大概位置」改為「精確位置」嗎?"</string> <string name="permgrouprequest_device_aware_fineupgrade" msgid="3947134846432067176">"要在<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上將「<xliff:g id="APP_NAME"><b>%1$s</b></xliff:g>」的位置資訊存取權從大概變更為精確嗎?"</string> - <string name="permgrouprequest_coarselocation" msgid="7244605063736425232">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取這部裝置的概略位置資訊嗎?"</string> + <string name="permgrouprequest_coarselocation" msgid="7244605063736425232">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>存取這部裝置的大概位置資訊嗎?"</string> <string name="permgrouprequest_device_aware_coarselocation" msgid="9001956706241104626">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」</b>存取<b><xliff:g id="DEVICE">%2$s</xliff:g></b>的大概位置嗎?"</string> <string name="permgrouprequest_finelocation_imagetext" msgid="1313062433398914334">"精確"</string> - <string name="permgrouprequest_coarselocation_imagetext" msgid="8650605041483025297">"概略"</string> + <string name="permgrouprequest_coarselocation_imagetext" msgid="8650605041483025297">"大概"</string> <string name="permgrouprequest_calendar" msgid="1493150855673603806">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取你的日曆嗎?"</string> <string name="permgrouprequest_device_aware_calendar" msgid="3103987548035171850">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<b></b>在<b><xliff:g id="DEVICE">%2$s</xliff:g></b>上存取你的日曆嗎?"</string> <string name="permgrouprequest_sms" msgid="5672063688745420991">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」傳送及查看簡訊嗎?"</string> @@ -546,7 +553,7 @@ <string name="blocked_camera_title" msgid="1128510551791284384">"裝置相機已封鎖"</string> <string name="blocked_microphone_title" msgid="1631517143648232585">"裝置麥克風已封鎖"</string> <string name="blocked_location_title" msgid="2005608279812892383">"裝置位置資訊已關閉"</string> - <string name="blocked_sensor_summary" msgid="4443707628305027375">"應用程式和服務"</string> + <string name="blocked_sensor_summary" msgid="4443707628305027375">"適用於應用程式和服務"</string> <string name="blocked_mic_summary" msgid="8960466941528458347">"當你撥打緊急電話號碼時,系統仍會提供麥克風的資料。"</string> <string name="blocked_sensor_button_label" msgid="6742092634984289658">"變更"</string> <string name="safety_center_dashboard_page_title" msgid="2810774008694315854">"安全性與隱私權"</string> @@ -608,9 +615,9 @@ <string name="privacy_controls_title" msgid="7605929972256835199">"隱私權控制項"</string> <string name="camera_toggle_title" msgid="1251201397431837666">"相機存取權"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"麥克風存取權"</string> - <string name="perm_toggle_description" msgid="7801326363741451379">"應用程式和服務"</string> + <string name="perm_toggle_description" msgid="7801326363741451379">"適用於應用程式和服務"</string> <string name="mic_toggle_description" msgid="9163104307990677157">"適用於應用程式和服務。即使關閉這項設定,系統仍可能會在你撥打緊急電話號碼時,分享麥克風資料。"</string> - <string name="location_settings_subtitle" msgid="2328360561197430695">"查看對位置擁有存取權的應用程式與服務"</string> + <string name="location_settings_subtitle" msgid="2328360561197430695">"查看可存取位置資訊的應用程式與服務"</string> <string name="show_clip_access_notification_title" msgid="5168467637351109096">"顯示剪貼簿存取通知"</string> <string name="show_clip_access_notification_summary" msgid="3532020182782112687">"系統會在應用程式存取你複製的文字、圖片或其他內容時顯示通知訊息"</string> <string name="show_password_title" msgid="2877269286984684659">"顯示密碼"</string> @@ -636,8 +643,8 @@ <string name="app_permission_rationale_message" msgid="8511466916077100713">"資料安全"</string> <string name="app_location_permission_rationale_title" msgid="925420340572401350">"可能會分享位置資料"</string> <string name="app_location_permission_rationale_subtitle" msgid="6986985722752868692">"這個應用程式表示可能會將位置資料分享給第三方"</string> - <string name="data_sharing_updates_title" msgid="7996933386875213859">"位置資料分享更新"</string> - <string name="data_sharing_updates_summary" msgid="764113985772233889">"查看哪些應用程式變更了分享位置資料的做法"</string> + <string name="data_sharing_updates_title" msgid="7996933386875213859">"位置資料共用方式更新"</string> + <string name="data_sharing_updates_summary" msgid="764113985772233889">"查看變更資料共用方式的應用程式"</string> <string name="data_sharing_updates_subtitle" msgid="6311537708950632329">"以下應用程式變更了分享位置資料的做法。這些應用程式先前可能未曾分享位置資料,也可能是現在為了廣告或行銷目的而分享這些資料。"</string> <string name="data_sharing_updates_footer_message" msgid="1582711655172892107">"這些應用程式的開發人員已將資料分享做法相關資訊提供給應用程式商店,並可能會隨著時間更新這些資訊。\n\n資料分享做法可能會因你的應用程式版本、使用方式、所在地區和年齡而異。"</string> <string name="learn_about_data_sharing" msgid="4200480587079488045">"瞭解資料分享"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"資料分享方式異動"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"部分應用程式改變了位置資料的分享方式"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"設定"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"上次存取時間:<xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"上次存取時間:昨天<xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"上次存取時間:<xliff:g id="TIME_DATE_0">%1$s</xliff:g><xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"你的動態密碼為 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"受限制的設定"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"為了安全起見,目前無法使用這項設定。"</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"系統已拒絕授予應用程式「<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>」存取權"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"這個應用程式要求取得私密資訊權限,授予這項權限可能導致你的個人資訊和財務資訊面臨風險。<xliff:g id="ID_1"><br><br></xliff:g>如果未取得這項受限制權限,應用程式可能無法正常運作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>瞭解如何授予權限</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"系統已拒絕授予應用程式做為預設「<xliff:g id="ROLE_NAME">%1$s</xliff:g>」的存取權"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"這個應用程式要求取得私密資訊權限,授予這些權限可能導致你的個人資訊和財務資訊面臨風險。<xliff:g id="ID_1"><br><br></xliff:g>如果未取得這些受限制權限,應用程式可能無法正常運作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>瞭解如何授予權限</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"系統已拒絕將存取權授予應用程式"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"如果授予這項權限,你的個人資訊和財務資訊可能會面臨風險。<xliff:g id="ID_1"><br><br></xliff:g>如果未取得這項受限制權限,應用程式可能無法正常運作。<a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>瞭解如何授予權限</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"瞭解詳情"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"確定"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"權限要求遭拒"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"這個應用程式要求額外權限,但串流期間無法授權。請先在手機上授予權限。"</string> </resources> diff --git a/PermissionController/res/values-zu-v34/strings.xml b/PermissionController/res/values-zu-v34/strings.xml index cb348a889..d960be6ee 100644 --- a/PermissionController/res/values-zu-v34/strings.xml +++ b/PermissionController/res/values-zu-v34/strings.xml @@ -23,5 +23,4 @@ <string name="health_connect_summary" msgid="815473513776882296">"Phatha ukufinyelela kwe-app kudatha yezempilo"</string> <string name="location_settings" msgid="8863940440881290182">"Setha indawo"</string> <string name="mic_toggle_description" msgid="1504101620086616040">"Okwama-app namasevisi. Uma leli sethingi livaliwe, idatha yemakrofoni ingabiwa uma ushayela inombolo yezimo eziphuthumayo."</string> - <string name="location_settings_subtitle" msgid="6846532794702613851">"Okwama-app namasevisi"</string> </resources> diff --git a/PermissionController/res/values-zu-watch/strings.xml b/PermissionController/res/values-zu-watch/strings.xml index 01b82fd1a..f314b0699 100644 --- a/PermissionController/res/values-zu-watch/strings.xml +++ b/PermissionController/res/values-zu-watch/strings.xml @@ -22,4 +22,11 @@ <string name="permission_summary_enforced_by_policy" msgid="2352478756952948019">"Akukwazi ukushintshwa"</string> <string name="generic_yes" msgid="2489207724988649846">"Yebo"</string> <string name="generic_cancel" msgid="2631708607129269698">"Khansela"</string> + <string name="permission_access_always" msgid="2107115233573823032">"Ngaso sonke isikhathi"</string> + <string name="permission_access_only_foreground" msgid="4412115020089923986">"Ngenkathi isebenzisa i-app"</string> + <string name="app_permission_button_allow_always" msgid="4920899432212307102">"Ngaso sonke isikhathi"</string> + <string name="app_permission_button_allow_foreground" msgid="7186980598244864830">"Ngenkathi isebenzisa i-app"</string> + <string name="grant_dialog_button_allow_always" msgid="7130695257254694576">"Ngaso sonke isikhathi"</string> + <string name="grant_dialog_button_allow_foreground" msgid="8917595344037255090">"Ngenkathi isebenzisa i-app"</string> + <string name="grant_dialog_button_allow_background" msgid="6104993390936535493">"Ngaso sonke isikhathi"</string> </resources> diff --git a/PermissionController/res/values-zu/strings.xml b/PermissionController/res/values-zu/strings.xml index 6fb918556..b945ecefe 100644 --- a/PermissionController/res/values-zu/strings.xml +++ b/PermissionController/res/values-zu/strings.xml @@ -51,7 +51,7 @@ <string name="permission_revoked_none" msgid="9213345075484381180">"Lutho olukhutshaziwe"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"Vumela"</string> <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Vumela sonke isikhathi"</string> - <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Ngenkathi usebenzisa uhlelo lokusebenza"</string> + <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Ngenkathi i-app"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"Shintshela kwindawo ngqo"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"Gcina indawo elinganiselwayo"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"Ngalesi sikhathi kuphela"</string> @@ -116,8 +116,6 @@ <string name="all_permissions" msgid="6911125611996872522">"Zonke izimvume"</string> <string name="other_permissions" msgid="2901186127193849594">"Amanye amakhono wohlelo lokusebenza"</string> <string name="permission_request_title" msgid="8790310151025020126">"Isicelo semvume"</string> - <string name="wear_not_allowed_dlg_title" msgid="1429467891296932713">"I-Android Wear"</string> - <string name="wear_not_allowed_dlg_text" msgid="512340555334769098">"Izenzo zokufaka/ukukhipha azisekelwe ku-Wear."</string> <string name="permission_review_title_template_install" msgid="1284337937156289081">"Khetha ukuthi uzovumela ini ukuthi i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifinyelele kuyo"</string> <string name="permission_review_title_template_update" msgid="3232333580548588657">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ibuyekeziwe. Khetha ukuthi uzovumela ini ukuthi ifinyelelwe ilolu hlelo lokusebenza."</string> <string name="review_button_cancel" msgid="2191147944056548886">"Khansela"</string> @@ -198,7 +196,8 @@ <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Sebenzisa indawo eqondile"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Uma indawo ngqo ivaliwe, ama-app angakwazi ukufinyelela indawo yakho elinganiselwayo"</string> <string name="app_permission_title" msgid="2090897901051370711">"<xliff:g id="PERM">%1$s</xliff:g> imvume"</string> - <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g> ukufinyelela kwale app"</string> + <string name="app_permission_header" msgid="2951363137032603806">"ukufinyelela kwale app ku<xliff:g id="PERM">%1$s</xliff:g>"</string> + <string name="app_permission_header_with_device_name" msgid="7193042925656173271">"Ukufinyelela kwe-<xliff:g id="PERM">%1$s</xliff:g> kwale app kuvuliwe ku-<xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="app_permission_footer_app_permissions_link" msgid="4926890342636587393">"Bona zonke izimvume ze-<xliff:g id="APP">%1$s</xliff:g>"</string> <string name="app_permission_footer_permission_apps_link" msgid="3941988129992794327">"Bona zonke izinhlelo zokusebenza ngale mvume"</string> <string name="assistant_mic_label" msgid="1011432357152323896">"Bonisa ukusetshenziswa kwe-microphone kamsizi"</string> @@ -206,7 +205,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Susa izimvume uma uhlelo lokusebenza lungasetshenziswa"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Susa izimvume uphinde ukhulule isikhala"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Misa okwesikhashana umsebenzi we-app uma ingasetshenziswa"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Lawula i-app uma ingasetsheziswa"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Susa izimvume, sula amafayela wesikhashana, futhi umise izaziso"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Susa izimvume, sula amafayela esikhashana, futhi ufake i-app kungobo yomlando"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Ukuze kuvikelwe idatha yakho, izimvume zalolu hlelo lokusebenza zizosuswa uma uhlelo lokusebenza lungasetshenziswa izinyanga ezimbalwa."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Ukuze kuvikelwe idatha yakho, uma uhlelo lokusebenza lungasetshenzisiwe, izimvume ezilandelayo zizosuswa: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Ukuze kuvikelwe idatha yakho, izimvume zisusiwe kusukela kuzinhlelo zokusebenza ongazange uzisebenzise ezinyangeni ezimbalwa."</string> @@ -254,6 +255,7 @@ <string name="allowed_storage_full" msgid="5356699280625693530">"Kuvumelekile ukuphatha wonke amafayela"</string> <string name="ask_header" msgid="2633816846459944376">"Buza njalo"</string> <string name="denied_header" msgid="903209608358177654">"Akuvumelekile"</string> + <string name="permission_group_name_with_device_name" msgid="8798741850536024820">"I-<xliff:g id="PERM_GROUP_NAME">%1$s</xliff:g> ku-<xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string> <string name="storage_footer_hyperlink_text" msgid="8873343987957834810">"Bona ama-app engeziwe akwazi ukufinyelela wonke amafayela"</string> <string name="days" msgid="609563020985571393">"{count,plural, =1{usuku 1}one{izinsuku #}other{izinsuku #}}"</string> <string name="hours" msgid="7302866489666950038">"{count,plural, =1{Ihora elingu-#}one{Amahora angu-#}other{Amahora angu-#}}"</string> @@ -403,6 +405,11 @@ <string name="role_notes_short_label" msgid="8796604147546125285">"I-App yamanothi"</string> <string name="role_notes_description" msgid="8496852798616883551">"Ama-app akuvumela ukuthi uthathe amanothi kudivayisi yakho"</string> <string name="role_notes_search_keywords" msgid="7710756695666744631">"amanothi"</string> + <string name="role_wallet_label" msgid="3719419175656204207">"I-app ye-wallet engokuzenzakalelayo"</string> + <string name="role_wallet_short_label" msgid="6521288403762457452">"I-app ye-wallet"</string> + <string name="role_wallet_description" msgid="3726535836165949838">"Ama-app e-Wallet angagcina amakhredithi kanye namakhadi obuqotho akho, izikhiye zemoto kanye nezinye izino ukukusiza ngezinhlobo ezihlukahlukene zokuthenga."</string> + <string name="role_wallet_request_title" msgid="4770217108262737093">"Setha i-<xliff:g id="APP_NAME">%1$s</xliff:g> njenge-app ye-wallet yakho ezenzakalelayo?"</string> + <string name="role_wallet_request_description" msgid="6305487425777483053">"Azikho izimvume ezidingekayo"</string> <string name="request_role_current_default" msgid="738722892438247184">"Okuzenzakalelayo kwamanje"</string> <string name="request_role_dont_ask_again" msgid="3556017886029520306">"Ungabuzi futhi"</string> <string name="request_role_set_as_default" msgid="4253949643984172880">"Setha njengokuzenzekelayo"</string> @@ -491,7 +498,7 @@ <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"Vumela i-<xliff:g id="APP_NAME">%1$s</xliff:g> ukuba ifinyelele izithombe namavidiyo kule divayisi?"</string> <string name="permgrouprequest_device_aware_read_media_visual" msgid="5492319750632751551">"Vumela <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuze ufinyelele izithombe namavidiyo <b>ku-<xliff:g id="DEVICE">%2$s</xliff:g></b> yakho?"</string> <string name="permgrouprequest_more_photos" msgid="128933814654231321">"Vumela <i-<xliff:g id="APP_NAME">%1$s</xliff:g>> ukuba ifinyelele izithombe namavidiyo kule divayisi?"</string> - <string name="permgrouprequest_device_aware_more_photos" msgid="8946782319103584021">"Vumela <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuze ufinyelele izithombe namavidiyo engeziwe <b>ku-<xliff:g id="DEVICE">%2$s</xliff:g></b> yakho?"</string> + <string name="permgrouprequest_device_aware_more_photos" msgid="8946782319103584021">"Vumela <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuze ufinyelele ezithombeni namavidiyo engeziwe <b>ku-<xliff:g id="DEVICE">%2$s</xliff:g></b> yakho?"</string> <string name="permgrouprequest_microphone" msgid="2825208549114811299">"Vumela i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuthi irekhode umsindo?"</string> <string name="permgrouprequest_device_aware_microphone" msgid="1266843551173029370">"Vumela <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuze urekhode umsindo <b>ku-<xliff:g id="DEVICE">%2$s</xliff:g></b> yakho?"</string> <string name="permgrouprequestdetail_microphone" msgid="8510456971528228861">"Uhlelo lokusebenza luzokwazi ukurekhoda imisindo kuphela kuyilapho usebenzisa uhlelo lokusebenza"</string> @@ -503,7 +510,7 @@ <string name="permgroupupgraderequestdetail_microphone" msgid="2870497719571464239">"Lolu hlelo lokusebenza lufuna ukurekhoda imisindo ngaso sonke isikhathi, ngisho nalapho ungasebenzisi uhlelo lokusebenza. "<annotation id="link">"Vumela kumasethingi."</annotation></string> <string name="permgrouprequest_activityRecognition" msgid="5415121592794230330">"Vumela i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuthi ifinyelele kumsebenzi wakho womzimba?"</string> <string name="permgrouprequest_device_aware_activityRecognition" msgid="3408326850847755759">"Vumela <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuze ufinyelele umsebenzi wakho womzimba <b>ku-<xliff:g id="DEVICE">%2$s</xliff:g></b> yakho?"</string> - <string name="permgrouprequest_camera" msgid="5123097035410002594">"Vumela i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuthatha izithombe iphinde irekhode ividiyo?"</string> + <string name="permgrouprequest_camera" msgid="5123097035410002594">"Vumela i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ithathe izithombe futhi irekhode ividiyo?"</string> <string name="permgrouprequest_device_aware_camera" msgid="3525106924487608868">"Vumela <b>i-<xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuthatha izithombe nokurekhoda ividiyo <b>ku-<xliff:g id="DEVICE">%2$s</xliff:g></b> yakho?"</string> <string name="permgrouprequestdetail_camera" msgid="9085323239764667883">"Lolu hlelo lokusebenza luzokwazi ukuthatha izithombe futhi lirekhode ividiyo kuphela kuyilapho usebenzisa uhlelo lokusebenza"</string> <string name="permgroupbackgroundrequest_camera" msgid="1274286575704213875">"Vumela i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuthatha izithombe iphinde irekhode ividiyo?"</string> @@ -648,4 +655,20 @@ <string name="safety_label_changes_notification_title" msgid="4479955083472203839">"Izibuyekezo zokwabelana ngedatha"</string> <string name="safety_label_changes_notification_desc" msgid="7808764283266234675">"Amanye ama-app aguqule indlela angabelana ngayo ngedatha yendawo yakho"</string> <string name="safety_label_changes_gear_description" msgid="2655887555599138509">"Amasethingi"</string> + <string name="wear_app_perms_24h_access" msgid="8668121661337328895">"Kufinyelelwe ngo-<xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_24h_access_yest" msgid="7069312481704735679">"Kufinyelelwe izolo ngo-<xliff:g id="TIME_DATE">%1$s</xliff:g>"</string> + <string name="wear_app_perms_7d_access" msgid="4608069019194676432">"Kufinyelelwe ngo-<xliff:g id="TIME_DATE_0">%1$s</xliff:g> <xliff:g id="TIME_DATE_1">%2$s</xliff:g>"</string> + <string name="test_otp_msg" msgid="7559110574222727550">"Iphasiwedi yakho yesikhathi esisodwa ithi 132435"</string> + <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Amasethingi akhawulelwe"</string> + <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Ukuze uphephe, leli sethingi okwamanje alitholakali."</string> + <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"I-app inqatshelwe ukufinyelela ku-<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> + <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"I-app icele ukufinyelela emvumweni ezwelayo okungabeka imininingwane yakho siqu neyezimali engozini.<xliff:g id="ID_1"><br><br></xliff:g>Kungenzeka ukuthi i-app ingasebenzi kahle ngaphandle kwemvume enomkhawulo. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Funda ukuthi ungakuvumela kanjani ukufinyelela</a>"</string> + <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"I-app iye yanqatshelwa ukufinyelela ukuze ibe yi-<xliff:g id="ROLE_NAME">%1$s</xliff:g> ezenzakalelayo"</string> + <string name="enhanced_confirmation_dialog_desc_role" msgid="6369601947905234551">"I-app icele ukufinyelela emvumweni ezwelayo engabeka ulwazi lwakho siqu nolwezimali engozini.<xliff:g id="ID_1"><br><br></xliff:g>Kungenzeka ukuthi i-app ingasebenzi kahle ngaphandle kwelezi zimvume ezinomkhawulo. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Funda ukuthi ungakuvumela kanjani ukufinyelela</a>"</string> + <string name="enhanced_confirmation_dialog_title_settings_default" msgid="1858092969721041576">"I-app iye yanqatshelwa ukufinyelela"</string> + <string name="enhanced_confirmation_dialog_desc_settings_default" msgid="6911632348359332981">"Ukufinyelela kule mvume kungabeka ulwazi lwakho siqu nolwezimali engozini.<xliff:g id="ID_1"><br><br></xliff:g>Kungenzeka ukuthi i-app ingasebenzi kahle ngaphandle kwemvume enomkhawulo. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>>Funda ukuthi ungakuvumela kanjani ukufinyelela</a>"</string> + <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Funda kabanzi"</string> + <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"KULUNGILE"</string> + <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Isicelo semvume sicindezelwe"</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Le-app icela izimvume ezengeziwe, kodwa izimvume azikwazi ukunikezwa ngesikhathi sokusakaza-bukhoma. Nikeza imvume kufoni yakho kuqala."</string> </resources> diff --git a/PermissionController/res/values/dimens.xml b/PermissionController/res/values/dimens.xml index f638e89df..53d5341fe 100644 --- a/PermissionController/res/values/dimens.xml +++ b/PermissionController/res/values/dimens.xml @@ -77,4 +77,5 @@ <dimen name="privhub_circle_stroke_width">8dp</dimen> <dimen name="privhub_details_recycler_view_bottom_padding">96dp</dimen> + </resources> diff --git a/PermissionController/res/values/overlayable.xml b/PermissionController/res/values/overlayable.xml index 8f81e446b..3f1a8d4a6 100644 --- a/PermissionController/res/values/overlayable.xml +++ b/PermissionController/res/values/overlayable.xml @@ -24,6 +24,7 @@ <!-- START HELP LINKS --> <item type="string" name="help_app_permissions" /> <item type="string" name="data_sharing_help_center_link" /> + <item type="string" name="help_url_action_disabled_by_restricted_settings" /> <!-- END HELP LINKS --> <!-- START PERMISSION GRANT DIALOG --> @@ -378,6 +379,35 @@ <item type="style" name="AppDataSharingUpdateSettingsIcon" /> <!-- END SAFETY LABELS STYLE --> + <!--START WEAR SPECIFIC FONT STRINGS --> + <item type="string" name="wear_material_compose_display_1_font_family" /> + <item type="string" name="wear_material_compose_display_2_font_family" /> + <item type="string" name="wear_material_compose_display_3_font_family" /> + <item type="string" name="wear_material_compose_title_1_font_family" /> + <item type="string" name="wear_material_compose_title_2_font_family" /> + <item type="string" name="wear_material_compose_title_3_font_family" /> + <item type="string" name="wear_material_compose_body_1_font_family" /> + <item type="string" name="wear_material_compose_body_2_font_family" /> + <item type="string" name="wear_material_compose_button_font_family" /> + <item type="string" name="wear_material_compose_caption_1_font_family" /> + <item type="string" name="wear_material_compose_caption_2_font_family" /> + <item type="string" name="wear_material_compose_caption_3_font_family" /> + <!--END WEAR SPECIFIC FONT STRINGS --> + + <!-- START ENHANCED CONFIRMATION DIALOG --> + <item type="style" name="Theme.EnhancedConfirmationDialog" /> + <item type="style" name="Theme.EnhancedConfirmationDialogFragment" /> + <item type="style" name="EnhancedConfirmationDialog" /> + <item type="style" name="EnhancedConfirmationDialogHeader" /> + <item type="style" name="EnhancedConfirmationDialogIcon" /> + <item type="style" name="EnhancedConfirmationDialogTitle" /> + <item type="style" name="EnhancedConfirmationDialogScrollView" /> + <item type="style" name="EnhancedConfirmationDialogBody" /> + <item type="style" name="EnhancedConfirmationDialogDesc" /> + <item type="style" name="EnhancedConfirmationDialogButtonBar" /> + <item type="style" name="EnhancedConfirmationDialogButton" /> + <!-- END ENHANCED CONFIRMATION DIALOG --> + </policy> </overlayable> diff --git a/PermissionController/res/values/strings.xml b/PermissionController/res/values/strings.xml index d10c6fb90..1932d92e2 100644 --- a/PermissionController/res/values/strings.xml +++ b/PermissionController/res/values/strings.xml @@ -624,6 +624,9 @@ <!-- Description for showing an app's permission [CHAR LIMIT=60] --> <string name="app_permission_header"><xliff:g id="perm" example="location">%1$s</xliff:g> access for this app</string> + <!-- Description for showing an app's permission along with device name [CHAR LIMIT=NONE] --> + <string name="app_permission_header_with_device_name"><xliff:g id="perm" example="camera">%1$s</xliff:g> access for this app on <xliff:g id="device_name" example="tablet">%2$s</xliff:g></string> + <!-- Text for linking to the page that shows an app's permissions [CHAR LIMIT=none] --> <string name="app_permission_footer_app_permissions_link">See all <xliff:g id="app" example="Maps">%1$s</xliff:g> permissions</string> @@ -645,9 +648,15 @@ <!-- Label for the hibernation / auto revoke switch on T+ devices [CHAR LIMIT=40] --> <string name="unused_apps_label_v2">Pause app activity if unused</string> + <!-- Label of a switch preference that controls whether the system will pause app activity when the app has not been used for a while [CHAR LIMIT=40]--> + <string name="unused_apps_label_v3">Manage app if unused</string> + <!-- Hibernation switch preference summary which describes what the toggle does on T+ devices [CHAR LIMIT=NONE] --> <string name="unused_apps_summary">Remove permissions, delete temporary files, and stop notifications</string> + <!-- Summary of the switch preference that controls whether the system will pause app activity when the app has not been used for a while [CHAR LIMIT=NONE]--> + <string name="unused_apps_summary_v2">Remove permissions, delete temporary files, stop notifications, and archive the app</string> + <!-- Summary for stating that permissions will be removed [CHAR LIMIT=none] --> <string name="auto_revoke_summary">To protect your data, permissions for this app will be removed if the app is unused for a few months.</string> @@ -793,6 +802,9 @@ <!-- Header for denied permissions/apps [CHAR LIMIT=40] --> <string name="denied_header">Not allowed</string> + <!-- Header to display the Permission group name along with corresponding device name [CHAR LIMIT=None] --> + <string name="permission_group_name_with_device_name"><xliff:g id="perm_group_name" example="camera">%1$s</xliff:g> on <xliff:g id="device_name" example="tablet">%2$s</xliff:g></string> + <!-- Text of hyperlink shown in storage_footer [CHAR LIMIT=60] --> <string name="storage_footer_hyperlink_text">See more apps that can access all files</string> @@ -1217,6 +1229,15 @@ <!-- Search keywords for the NOTES role. [CHAR LIMIT=NONE] --> <string name="role_notes_search_keywords">notes</string> + <!-- Label for the wallet role. [CHAR LIMIT=30] --> + <string name="role_wallet_label">Default wallet app</string> + <!-- Short label for the wallet role. [CHAR LIMIT=30] --> + <string name="role_wallet_short_label">Wallet app</string> + <!-- Description for the wallet role. [CHAR LIMIT=NONE] --> + <string name="role_wallet_description">Wallet apps can store your credit and loyalty cards, car keys and other things to help with various forms of transactions.</string> + <string name="role_wallet_request_title">Set <xliff:g id="app_name" example="Super Wallet">%1$s</xliff:g> as your default wallet app?</string> + <string name="role_wallet_request_description">No permissions needed</string> + <!-- Subtitle for the application that is the current default application [CHAR LIMIT=30] --> <string name="request_role_current_default">Current default</string> @@ -1291,6 +1312,9 @@ <!-- Title for category of default apps for work [CHAR LIMIT=30] --> <string name="default_apps_for_work">Default for work</string> + <!-- Title for category of default apps for private profile [CHAR LIMIT=50] --> + <string name="default_apps_for_private_profile">Default for private space</string> + <!-- Summary of a default app when there is no app set [CHAR LIMIT=60] --> <string name="default_app_none">None</string> @@ -1633,6 +1657,8 @@ Allow <xliff:g id="app_name" example="Gmail">%4$s</xliff:g> to upload a bug repo <string name="privdash_label_24h">Past\n24 hours</string> <!-- Label that describes a "past 7 days" time window, prefer two lines. [CHAR LIMIT=20] --> <string name="privdash_label_7d">Past\n7 days</string> + <!-- This information will aid accessibility applications in describing permission usage percentages to users. While the chart visually represents permission usage, accessibility tools will convey the specific percentages for those who need auditory assistance. Examples would be "Microphone 40 percent" or "Location 75 percent" [CHAR LIMIT=none] --> + <string name="privdash_usage_percent"><xliff:g id="permission_name" example="camera">%1$s</xliff:g> <xliff:g id="percent" example="25">%2$d</xliff:g> percent</string> <!-- Info label for status bar indicator permissions (Mic and Camera) for apps holding special exempted roles. [CHAR LIMIT=none] --> <string name="exempt_mic_camera_info_label"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> is protected by Android. Because your data is processed on this device, this app’s permission usage isn’t shown on the status bar or your privacy dashboard. </string> @@ -1934,4 +1960,51 @@ Allow <xliff:g id="app_name" example="Gmail">%4$s</xliff:g> to upload a bug repo <string name="safety_label_changes_gear_description">Settings</string> <!-- Safety Label Change Notifications End --> + + <!-- Summary for showing the last access text for today for Wear [CHAR LIMIT=50] --> + <string name="wear_app_perms_24h_access">Accessed <xliff:g id="time_date" example="12:42 PM">%1$s</xliff:g></string> + + <!-- Summary for showing the last access text for yesterday for Wear [CHAR LIMIT=50] --> + <string name="wear_app_perms_24h_access_yest">Accessed yesterday <xliff:g id="time_date" example="12:42 PM">%1$s</xliff:g></string> + + <!-- Summary for showing the last access text for 7 days for Wear [CHAR LIMIT=50] --> + <string name="wear_app_perms_7d_access">Accessed <xliff:g id="time_date" example="Jan 3">%1$s</xliff:g> <xliff:g id="time_date" example="12:42 PM">%2$s</xliff:g></string> + + <!-- A string representing a message (sms, email, etc.) telling the user about a one time password. Used for testing [CHAR LIMIT=NONE] --> + <string name="test_otp_msg">Your one time password is 132435</string> + + <!-- START ENHANCED CONFIRMATION DIALOG --> + + <!--Title for dialog displayed to tell user that settings are blocked by setting restrictions [CHAR LIMIT=50] --> + <string name="enhanced_confirmation_dialog_title">Restricted setting</string> + <!--Content for dialog displayed to tell user that settings are blocked by setting restrictions [CHAR LIMIT=NONE] --> + <string name="enhanced_confirmation_dialog_desc">For your security, this setting is currently unavailable.</string> + + <!--Title for dialog displayed to tell user that permissions are blocked by setting restrictions [CHAR LIMIT=50] --> + <string name="enhanced_confirmation_dialog_title_permission">App was denied access to <xliff:g id="permission_name" example="contacts">%1$s</xliff:g></string> + <!--Content for dialog displayed to tell user that settings are blocked by setting restrictions [CHAR LIMIT=NONE] --> + <string name="enhanced_confirmation_dialog_desc_permission">The app requested access to a sensitive permission which can put your personal and financial info at risk.<xliff:g><br><br></xliff:g>It\'s possible the app won\'t work properly without this restricted permission. <a href="<xliff:g id="learn_more_link">%1$s</xliff:g>">Learn how to allow access</a></string> + + <string name="enhanced_confirmation_dialog_title_role">App was denied access to be default <xliff:g id="role_name" example="phone app">%1$s</xliff:g></string> + <!--Content for dialog displayed to tell user that settings are blocked by setting restrictions [CHAR LIMIT=NONE] --> + <string name="enhanced_confirmation_dialog_desc_role">The app requested access to sensitive permissions which can put your personal and financial info at risk.<xliff:g><br><br></xliff:g>It\'s possible the app won\'t work properly without these restricted permissions. <a href="<xliff:g id="learn_more_link">%1$s</xliff:g>">Learn how to allow access</a></string> + + <string name="enhanced_confirmation_dialog_title_settings_default">App was denied access</string> + <!--Content for dialog displayed to tell user that settings are blocked by setting restrictions [CHAR LIMIT=NONE] --> + <string name="enhanced_confirmation_dialog_desc_settings_default">Access to this permission can put your personal and financial info at risk.<xliff:g><br><br></xliff:g>It\'s possible the app won\'t work properly without this restricted permission. <a href="<xliff:g id="learn_more_link">%1$s</xliff:g>">Learn how to allow access</a></string> + + <!-- Button label to allow the user to view additional information [CHAR LIMIT=NONE] --> + <string name="enhanced_confirmation_dialog_learn_more">Learn more</string> + <!-- Button label of the ok button [CHAR LIMIT=NONE] --> + <string name="enhanced_confirmation_dialog_ok">OK</string> + <!-- Help URI, action disabled by restricted settings [DO NOT TRANSLATE] --> + <string name="help_url_action_disabled_by_restricted_settings" translatable="false"></string> + + <!-- END ENHANCED CONFIRMATION DIALOG --> + + <!-- Title for the warning dialog that shows when permission grant dialog is blocked from streaming to a remote device [CHAR LIMIT=70]--> + <string name="permission_grant_dialog_streaming_blocked_title">Permission request suppressed</string> + + <!-- Descriptions for the warning dialog that shows when permission grant dialog is blocked from streaming to a remote device [CHAR LIMIT=200] --> + <string name="permission_grant_dialog_streaming_blocked_description">This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your phone first.</string> </resources> diff --git a/PermissionController/res/values/styles.xml b/PermissionController/res/values/styles.xml index a03b71e9d..a4e859587 100644 --- a/PermissionController/res/values/styles.xml +++ b/PermissionController/res/values/styles.xml @@ -195,6 +195,8 @@ <item name="android:paddingEnd">16dp</item> <item name="android:orientation">horizontal</item> <item name="android:background">@drawable/grant_dialog_permission_rationale_background</item> + <item name="android:minWidth">48dp</item> + <item name="android:minHeight">48dp</item> </style> <style name="PermissionGrantPermissionRationaleIcon"> @@ -1036,6 +1038,7 @@ <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_marginStart">16dp</item> + <item name="android:background">@null</item> </style> <!-- END REQUEST ROLE DIALOG ITEM --> @@ -1294,4 +1297,71 @@ <!-- END WARNING BANNER --> + <!-- START ENHANCED CONFIRMATION DIALOG --> + + <style name="EnhancedConfirmationDialog"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:orientation">vertical</item> + <item name="android:paddingTop">24dp</item> + <item name="android:paddingStart">24dp</item> + <item name="android:paddingEnd">24dp</item> + <item name="android:paddingBottom">16dp</item> + </style> + + <style name="EnhancedConfirmationDialogHeader"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:orientation">vertical</item> + <item name="android:gravity">center_horizontal</item> + <item name="android:paddingBottom">16dp</item> + </style> + + <style name="EnhancedConfirmationDialogIcon"> + <item name="android:src">@drawable/ic_safety_center_shield</item> + <item name="android:layout_width">32dp</item> + <item name="android:layout_height">32dp</item> + <item name="android:scaleType">fitCenter</item> + <item name="android:tint">?android:attr/colorAccent</item> + <item name="android:contentDescription">@null</item> + </style> + + <style name="EnhancedConfirmationDialogTitle" parent="@android:style/TextAppearance.Material.Headline"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_marginTop">16dp</item> + <item name="android:gravity">center_horizontal</item> + </style> + + <style name="EnhancedConfirmationDialogScrollView"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:fadeScrollbars">false</item> + </style> + <style name="EnhancedConfirmationDialogBody"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:orientation">vertical</item> + </style> + <style name="EnhancedConfirmationDialogDesc" parent="@android:style/TextAppearance.Material.Body1"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:gravity">left</item> + <item name="android:fontFamily">google-sans-text</item> + <item name="android:textSize">14sp</item> + <item name="android:lineSpacingMultiplier">1.2</item> + </style> + + <style name="EnhancedConfirmationDialogButtonBar"> + <item name="android:paddingBottom">14dp</item> + <item name="android:paddingTop">12dp</item> + </style> + + <style name="EnhancedConfirmationDialogButton"> + <item name="android:fontFamily">google-sans-medium</item> + <item name="android:textSize">14sp</item> + <item name="android:lineSpacingMultiplier">1.25</item> + </style> + + <!-- END ENHANCED CONFIRMATION DIALOG --> </resources> diff --git a/PermissionController/res/values/themes.xml b/PermissionController/res/values/themes.xml index 4f59ec29d..2e6af4af1 100644 --- a/PermissionController/res/values/themes.xml +++ b/PermissionController/res/values/themes.xml @@ -107,6 +107,11 @@ <style name="Theme.DeviceDefault.Dialog.NoActionBar.DayNight" parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar" /> + <!-- + TODO(b/309578419): Make activities handle insets properly and then remove this. + --> + <style name="OptOutEdgeToEdgeEnforcement" /> + <!-- Do not allow OEMs to overlay these themes. Must Guarantee that filterTouches is set for these activities --> @@ -138,6 +143,27 @@ <item name="android:filterTouchesWhenObscured">true</item> </style> + <style name="Theme.EnhancedConfirmationDialog.FilterTouches" parent="Theme.EnhancedConfirmationDialog"> + <item name="android:filterTouchesWhenObscured">true</item> + </style> + <style name="Theme.PermissionController.IncidentReportDialog" parent="@style/Theme.DeviceDefault.Dialog.NoActionBar.DayNight" /> + + <!-- START ENHANCED CONFIRMATION DIALOG --> + + <style name="Theme.EnhancedConfirmationDialog" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar"> + <item name="windowNoTitle">true</item> + <item name="android:alertDialogTheme">@style/Theme.EnhancedConfirmationDialogFragment</item> + <item name="android:buttonBarStyle">@style/EnhancedConfirmationDialogButtonBar</item> + <item name="android:buttonBarPositiveButtonStyle">@style/EnhancedConfirmationDialogButton</item> + <item name="android:buttonBarNegativeButtonStyle">@style/EnhancedConfirmationDialogButton</item> + <item name="android:buttonBarNeutralButtonStyle">@style/EnhancedConfirmationDialogButton</item> + </style> + + <style name="Theme.EnhancedConfirmationDialogFragment" parent="@android:style/Theme.DeviceDefault.Dialog.Alert"> + <item name="android:buttonBarStyle">@style/EnhancedConfirmationDialogButtonBar</item> + </style> + + <!-- END ENHANCED CONFIRMATION DIALOG --> </resources> diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml index 497bfbeb5..78bb8a7cb 100644 --- a/PermissionController/res/xml/roles.xml +++ b/PermissionController/res/xml/roles.xml @@ -141,6 +141,10 @@ minSdkVersion="33" /> <permission name="android.permission.EXECUTE_APP_ACTION" minSdkVersion="34" /> + <permission name="android.permission.MANAGE_CONTENT_SUGGESTIONS" + minSdkVersion="35" optionalMinSdkVersion="34" /> + <permission name="android.permission.EMBED_ANY_APP_IN_UNTRUSTED_MODE" + minSdkVersion="35" /> </permissions> <app-op-permissions> <app-op-permission name="android.permission.SYSTEM_ALERT_WINDOW" /> @@ -444,7 +448,9 @@ </preferred-activity> </preferred-activities> <permissions> - <permission name="android.permission.READ_HOME_APP_SEARCH_DATA" minSdkVersion="33"/> + <permission name="android.permission.READ_HOME_APP_SEARCH_DATA" minSdkVersion="33" /> + <permission name="android.permission.ALLOW_SLIPPERY_TOUCHES" minSdkVersion="33" optionalMinSdkVersion="30" /> + <permission name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" minSdkVersion="35" /> </permissions> </role> @@ -516,7 +522,7 @@ <role name="android.app.role.SYSTEM_AUTOMOTIVE_CLUSTER" - behavior="AutomotiveRoleBehavior" + behavior="v31.AutomotiveRoleBehavior" defaultHolders="config_systemAutomotiveCluster" exclusive="true" minSdkVersion="31" @@ -533,7 +539,7 @@ <role name="android.app.role.COMPANION_DEVICE_WATCH" - behavior="CompanionDeviceWatchRoleBehavior" + behavior="v31.CompanionDeviceWatchRoleBehavior" description="@string/role_watch_description" exclusive="false" minSdkVersion="31" @@ -546,6 +552,9 @@ <permission-set name="contacts" /> <permission-set name="nearby_devices" /> <permission-set name="notifications" minSdkVersion="35" /> + <!-- If this role holder has a NotificationListenerService, let that service receive + notifications with sensitive content unredacted--> + <permission name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" minSdkVersion="35"/> </permissions> <app-op-permissions> <app-op-permission name="android.permission.MANAGE_ONGOING_CALLS" /> @@ -581,12 +590,15 @@ <permission name="android.permission.TOGGLE_AUTOMOTIVE_PROJECTION" minSdkVersion="33" /> <permission name="android.permission.ADD_TRUSTED_DISPLAY" minSdkVersion="34"/> <permission name="android.permission.ASSOCIATE_COMPANION_DEVICES" minSdkVersion="34"/> + <!-- If this role holder has a NotificationListenerService, let that service receive + notifications with sensitive content unredacted--> + <permission name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" minSdkVersion="35"/> </permissions> </role> <role name="android.app.role.SYSTEM_SHELL" - behavior="SystemShellRoleBehavior" + behavior="v31.SystemShellRoleBehavior" defaultHolders="config_systemShell" exclusive="true" minSdkVersion="31" @@ -631,6 +643,8 @@ <permission name="android.permission.MANAGE_DEVICE_POLICY_CALLS" minSdkVersion="34" /> <permission name="android.permission.MANAGE_DEVICE_POLICY_CAMERA" minSdkVersion="34" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION" + minSdkVersion="35" /> <permission name="android.permission.MANAGE_DEVICE_POLICY_DEBUGGING_FEATURES" minSdkVersion="34" /> <permission name="android.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET" @@ -670,6 +684,10 @@ <permission name="android.permission.SET_TIME_ZONE" minSdkVersion="34" /> <permission name="android.permission.SATELLITE_COMMUNICATION" minSdkVersion="34" /> <permission name="android.permission.ALWAYS_UPDATE_WALLPAPER" minSdkVersion="35" /> + <permission name="android.permission.EMBED_ANY_APP_IN_UNTRUSTED_MODE" + minSdkVersion="35" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" + minSdkVersion="35" /> </permissions> </role> @@ -753,7 +771,7 @@ --> <role name="android.app.role.SYSTEM_TELEVISION_NOTIFICATION_HANDLER" - behavior="TelevisionRoleBehavior" + behavior="v31.TelevisionRoleBehavior" defaultHolders="config_systemTelevisionNotificationHandler" exclusive="true" minSdkVersion="31" @@ -962,6 +980,9 @@ <permission-set name="notifications" /> <permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" /> <permission name="android.permission.SYSTEM_APPLICATION_OVERLAY" /> + <!-- If this role holder has a NotificationListenerService, let that service receive + notifications with sensitive content unredacted--> + <permission name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" minSdkVersion="35"/> </permissions> </role> @@ -1053,7 +1074,7 @@ --> <role name="android.app.role.SYSTEM_DOCUMENT_MANAGER" - behavior="DocumentManagerRoleBehavior" + behavior="v33.DocumentManagerRoleBehavior" exclusive="true" minSdkVersion="33" static="true" @@ -1115,6 +1136,9 @@ <permission name="android.permission.MANAGE_SENSOR_PRIVACY" /> <permission name="android.permission.OBSERVE_SENSOR_PRIVACY" /> <permission name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT" minSdkVersion="33"/> + <!-- If this role holder has a NotificationListenerService, let that service receive + notifications with sensitive content unredacted--> + <permission name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" minSdkVersion="35"/> </permissions> </role> @@ -1123,7 +1147,7 @@ --> <role name="android.app.role.SYSTEM_TELEVISION_REMOTE_SERVICE" - behavior="TelevisionRoleBehavior" + behavior="v31.TelevisionRoleBehavior" defaultHolders="config_systemTelevisionRemoteService" exclusive="true" minSdkVersion="31" @@ -1142,7 +1166,7 @@ <role name="android.app.role.COMPANION_DEVICE_APP_STREAMING" allowBypassingQualification="true" - behavior="CompanionDeviceAppStreamingRoleBehavior" + behavior="v33.CompanionDeviceAppStreamingRoleBehavior" description="@string/role_app_streaming_description" exclusive="false" minSdkVersion="33" @@ -1168,7 +1192,7 @@ <role name="android.app.role.COMPANION_DEVICE_COMPUTER" allowBypassingQualification="true" - behavior="CompanionDeviceComputerRoleBehavior" + behavior="v33.CompanionDeviceComputerRoleBehavior" description="@string/role_companion_device_computer_description" exclusive="false" minSdkVersion="33" @@ -1177,12 +1201,15 @@ <permissions> <permission-set name="notifications" /> <permission-set name="storage" /> + <!-- If this role holder has a NotificationListenerService, let that service receive + notifications with sensitive content unredacted--> + <permission name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" minSdkVersion="35"/> </permissions> </role> <role name="android.app.role.COMPANION_DEVICE_GLASSES" - behavior="CompanionDeviceGlassesRoleBehavior" + behavior="v34.CompanionDeviceGlassesRoleBehavior" exclusive="false" minSdkVersion="34" systemOnly="false" @@ -1194,6 +1221,9 @@ <permission-set name="notifications" /> <permission-set name="phone" /> <permission-set name="sms" /> + <!-- If this role holder has a NotificationListenerService, let that service receive + notifications with sensitive content unredacted--> + <permission name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" minSdkVersion="35"/> </permissions> <app-op-permissions> <app-op-permission name="android.permission.MANAGE_ONGOING_CALLS" /> @@ -1238,7 +1268,7 @@ --> <role name="android.app.role.DEVICE_POLICY_MANAGEMENT" - behavior="DevicePolicyManagementRoleBehavior" + behavior="v33.DevicePolicyManagementRoleBehavior" defaultHolders="config_devicePolicyManagement" exclusive="true" minSdkVersion="33" @@ -1331,6 +1361,13 @@ <permission name="android.permission.MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER" minSdkVersion="34" /> <permission name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL" minSdkVersion="34" /> <permission name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS" minSdkVersion="34" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION" minSdkVersion="35" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES" minSdkVersion="35" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL" minSdkVersion="35" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_CAMERA_TOGGLE" minSdkVersion="35" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE" minSdkVersion="35" /> + <permission name="android.permission.QUERY_DEVICE_STOLEN_STATE" minSdkVersion="35" /> + <permission name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" minSdkVersion="35" /> </permissions> </role> @@ -1345,6 +1382,9 @@ <permissions> <permission-set name="notifications" /> <permission name="android.permission.GET_HISTORICAL_APP_OPS_STATS" /> + <permission name="android.permission.READ_SMS" /> + <permission name="android.permission.RECEIVE_SMS" /> + <permission name="android.permission.GET_BACKGROUND_INSTALLED_PACKAGES" minSdkVersion="35" /> </permissions> </role> @@ -1354,7 +1394,7 @@ --> <role name="android.app.role.SYSTEM_AUTOMOTIVE_CALENDAR_SYNC_MANAGER" - behavior="AutomotiveRoleBehavior" + behavior="v31.AutomotiveRoleBehavior" defaultHolders="config_systemAutomotiveCalendarSyncManager" exclusive="true" minSdkVersion="33" @@ -1374,7 +1414,7 @@ --> <role name="android.app.role.AUTOMOTIVE_NAVIGATION" - behavior="AutomotiveRoleBehavior" + behavior="v31.AutomotiveRoleBehavior" defaultHolders="config_defaultAutomotiveNavigation" description="@string/role_automotive_navigation_description" exclusive="true" @@ -1531,7 +1571,7 @@ --> <role name="android.app.role.SYSTEM_WEAR_HEALTH_SERVICE" - behavior="SystemWearHealthServiceRoleBehavior" + behavior="v33.SystemWearHealthServiceRoleBehavior" defaultHolders="config_systemWearHealthService" exclusive="true" minSdkVersion="33" @@ -1551,7 +1591,7 @@ --> <role name="android.app.role.NOTES" - behavior="NotesRoleBehavior" + behavior="v34.NotesRoleBehavior" defaultHolders="config_defaultNotes" description="@string/role_notes_description" exclusive="true" @@ -1615,7 +1655,7 @@ <role name="android.app.role.RETAIL_DEMO" - behavior="RetailDemoRoleBehavior" + behavior="v35.RetailDemoRoleBehavior" defaultHolders="config_defaultRetailDemo" exclusive="true" minSdkVersion="35" @@ -1637,4 +1677,22 @@ <app-op-permission name="android.permission.PACKAGE_USAGE_STATS" /> </app-op-permissions> </role> + + <role + name="android.app.role.WALLET" + behavior="v35.WalletRoleBehavior" + defaultHolders="config_defaultWallet" + description="@string/role_wallet_description" + exclusive="true" + label="@string/role_wallet_label" + minSdkVersion="35" + overrideUserWhenGranting="true" + requestable="true" + requestDescription="@string/role_wallet_request_description" + requestTitle="@string/role_wallet_request_title" + showNone="true" + shortLabel="@string/role_wallet_short_label" + uiBehavior="v35.WalletRoleUiBehavior"/> + + </roles> diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/HomeRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/HomeRoleBehavior.java index 4bf5a6294..8c1446b50 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/HomeRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/HomeRoleBehavior.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.os.Build; import android.os.UserHandle; @@ -148,13 +147,6 @@ public class HomeRoleBehavior implements RoleBehavior { true, false, true, false, false, user, context); } - // Before T, ALLOW_SLIPPERY_TOUCHES may either not exist, or may not be a role permission - if (isRolePermission(android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES, context)) { - Permissions.grantAsUser(packageName, - Arrays.asList(android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES), - true, false, true, false, false, user, context); - } - if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) { if (SdkLevel.isAtLeastT()) { Permissions.grantAsUser(packageName, WEAR_PERMISSIONS_T, @@ -178,13 +170,6 @@ public class HomeRoleBehavior implements RoleBehavior { user, context); } - // Before T, ALLOW_SLIPPERY_TOUCHES may either not exist, or may not be a role permission - if (isRolePermission(android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES, context)) { - Permissions.revokeAsUser(packageName, - Arrays.asList(android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES), - true, false, false, user, context); - } - if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) { if (SdkLevel.isAtLeastT()) { Permissions.revokeAsUser(packageName, WEAR_PERMISSIONS_T, true, false, false, @@ -200,21 +185,6 @@ public class HomeRoleBehavior implements RoleBehavior { } } - /** - * Return true if the permission exists, and has 'role' protection level. - * Return false otherwise. - */ - private boolean isRolePermission(@NonNull String permissionName, @NonNull Context context) { - PermissionInfo permissionInfo; - try { - permissionInfo = context.getPackageManager().getPermissionInfo(permissionName, 0); - } catch (PackageManager.NameNotFoundException e) { - return false; - } - final int flags = permissionInfo.getProtectionFlags(); - return (flags & PermissionInfo.PROTECTION_FLAG_ROLE) == PermissionInfo.PROTECTION_FLAG_ROLE; - } - @Override public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/AutomotiveRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/AutomotiveRoleBehavior.java index 6eedb8f4d..022e127e6 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/AutomotiveRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/AutomotiveRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v31; import android.content.Context; import android.content.pm.PackageManager; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceWatchRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/CompanionDeviceWatchRoleBehavior.java index 0645c84d1..b98035fb2 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceWatchRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/CompanionDeviceWatchRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v31; import android.content.Context; import android.os.UserHandle; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/SystemShellRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/SystemShellRoleBehavior.java index 621955770..8c6eafa26 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/SystemShellRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/SystemShellRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v31; import android.content.Context; import android.content.pm.PackageManager; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/TelevisionRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/TelevisionRoleBehavior.java index 88021e62d..d418ba300 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/TelevisionRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v31/TelevisionRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v31; import android.content.Context; import android.content.pm.PackageManager; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceAppStreamingRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/CompanionDeviceAppStreamingRoleBehavior.java index c164de3d8..275387d57 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceAppStreamingRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/CompanionDeviceAppStreamingRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v33; import android.content.Context; import android.os.UserHandle; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceComputerRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/CompanionDeviceComputerRoleBehavior.java index e5d996675..9967751ed 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceComputerRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/CompanionDeviceComputerRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v33; import android.content.Context; import android.os.UserHandle; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/DevicePolicyManagementRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/DevicePolicyManagementRoleBehavior.java index 648b7d198..34e7e1843 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/DevicePolicyManagementRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/DevicePolicyManagementRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v33; import android.app.admin.DevicePolicyManager; import android.content.Context; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/DocumentManagerRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/DocumentManagerRoleBehavior.java index fa030a00a..3fb7b2c56 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/DocumentManagerRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/DocumentManagerRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v33; import android.content.Context; import android.os.UserHandle; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/SystemWearHealthServiceRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/SystemWearHealthServiceRoleBehavior.java index d9f34291d..446bdac84 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/SystemWearHealthServiceRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v33/SystemWearHealthServiceRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v33; import android.content.Context; import android.content.pm.PackageManager; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceGlassesRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v34/CompanionDeviceGlassesRoleBehavior.java index 5464a1518..00d7e5f31 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/CompanionDeviceGlassesRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v34/CompanionDeviceGlassesRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v34; import android.content.Context; import android.os.UserHandle; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/NotesRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v34/NotesRoleBehavior.java index 14c189a0f..4e39e0c87 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/NotesRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v34/NotesRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v34; import android.content.Context; import android.content.res.Resources; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/RetailDemoRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v35/RetailDemoRoleBehavior.java index 6dcdafd4c..9905ed0ae 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/behavior/RetailDemoRoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v35/RetailDemoRoleBehavior.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.role.controller.behavior; +package com.android.role.controller.behavior.v35; import android.app.admin.DevicePolicyManager; import android.content.Context; diff --git a/PermissionController/role-controller/java/com/android/role/controller/behavior/v35/WalletRoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/behavior/v35/WalletRoleBehavior.java new file mode 100644 index 000000000..d01e59456 --- /dev/null +++ b/PermissionController/role-controller/java/com/android/role/controller/behavior/v35/WalletRoleBehavior.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.role.controller.behavior.v35; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.nfc.cardemulation.ApduServiceInfo; +import android.nfc.cardemulation.CardEmulation; +import android.nfc.cardemulation.HostApduService; +import android.nfc.cardemulation.OffHostApduService; +import android.os.Build; +import android.os.UserHandle; +import android.permission.flags.Flags; +import android.service.quickaccesswallet.QuickAccessWalletService; +import android.util.ArraySet; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; + +import com.android.modules.utils.build.SdkLevel; +import com.android.role.controller.model.Role; +import com.android.role.controller.model.RoleBehavior; +import com.android.role.controller.util.CollectionUtils; +import com.android.role.controller.util.UserUtils; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + * Handles the behavior of the wallet role. + */ +@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) +public class WalletRoleBehavior implements RoleBehavior { + + private static final String LOG_TAG = WalletRoleBehavior.class.getSimpleName(); + + @Override + public boolean isAvailableAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return SdkLevel.isAtLeastV() && Flags.walletRoleEnabled() + && !UserUtils.isProfile(user, context); + } + + @Nullable + @Override + public List<String> getDefaultHoldersAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + Context userContext = UserUtils.getUserContext(context, user); + ComponentName preferredPaymentService = + CardEmulation.getPreferredPaymentService(userContext); + if (preferredPaymentService != null) { + return Collections.singletonList(preferredPaymentService.getPackageName()); + } + + return null; + } + + @Nullable + @Override + public String getFallbackHolderAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return CollectionUtils.firstOrNull(role.getDefaultHoldersAsUser(user, context)); + } + + @Nullable + @Override + public Boolean isPackageQualifiedAsUser(@NonNull Role role, @NonNull String packageName, + @NonNull UserHandle user, @NonNull Context context) { + return !getQualifyingPackageNamesInternal(packageName, user, context).isEmpty(); + } + + @Nullable + @Override + public List<String> getQualifyingPackagesAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return new ArrayList<>(getQualifyingPackageNamesInternal(null, user, context)); + } + + @NonNull + private static Set<String> getQualifyingPackageNamesInternal(@Nullable String packageName, + @NonNull UserHandle user, @NonNull Context context) { + Set<String> packageNames = resolvePackageNames(QuickAccessWalletService.SERVICE_INTERFACE, + packageName, user, context); + if (isNfcHostCardEmulationSupported(context)) { + packageNames.addAll(getQualifyingApduServicesAsUser(packageName, false, user, + context)); + packageNames.addAll(getQualifyingApduServicesAsUser(packageName, true, user, + context)); + } + return packageNames; + } + + @NonNull + private static Set<String> resolvePackageNames(@NonNull String action, + @Nullable String packageName, @NonNull UserHandle user, @NonNull Context context) { + Intent intent = new Intent(action).setPackage(packageName); + PackageManager packageManager = context.getPackageManager(); + List<ResolveInfo> resolveInfos = packageManager + .queryIntentServicesAsUser(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, user); + Set<String> packageNames = new ArraySet<>(); + int resolveInfosSize = resolveInfos.size(); + for (int i = 0; i < resolveInfosSize; i++) { + ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo; + if (!serviceInfo.exported) { + continue; + } + packageNames.add(serviceInfo.packageName); + } + return packageNames; + } + + @NonNull + private static Set<String> getQualifyingApduServicesAsUser(@Nullable String packageName, + boolean onHost, @NonNull UserHandle user, @NonNull Context context) { + Context userContext = UserUtils.getUserContext(context, user); + PackageManager userPackageManager = userContext.getPackageManager(); + Intent intent = new Intent( + onHost ? HostApduService.SERVICE_INTERFACE : OffHostApduService.SERVICE_INTERFACE) + .setPackage(packageName); + List<ResolveInfo> resolveInfos = userPackageManager.queryIntentServices(intent, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.GET_META_DATA); + Set<String> packageNames = new ArraySet<>(); + int resolveInfosSize = resolveInfos.size(); + for (int i = 0; i < resolveInfosSize; i++) { + ResolveInfo resolveInfo = resolveInfos.get(i); + ServiceInfo serviceInfo = resolveInfo.serviceInfo; + if (!serviceInfo.exported) { + continue; + } + ApduServiceInfo apduServiceInfo; + try { + apduServiceInfo = new ApduServiceInfo(userPackageManager, resolveInfo, onHost); + } catch (IOException | XmlPullParserException e) { + Log.w(LOG_TAG, "Unable to create ApduServiceInfo for " + resolveInfo, e); + continue; + } + if (apduServiceInfo.hasCategory(CardEmulation.CATEGORY_PAYMENT)) { + packageNames.add(resolveInfo.serviceInfo.packageName); + } + } + return packageNames; + } + + private static boolean isNfcHostCardEmulationSupported(@NonNull Context context) { + return context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_NFC_HOST_CARD_EMULATION); + } +} diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java b/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java index 6ded32d58..f999e5972 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java @@ -16,11 +16,16 @@ package com.android.role.controller.model; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.PermissionInfo; import android.os.Build; +import android.os.UserHandle; import androidx.annotation.NonNull; import com.android.modules.utils.build.SdkLevel; +import com.android.role.controller.util.UserUtils; import java.util.Objects; @@ -40,9 +45,15 @@ public class Permission { */ private final int mMinSdkVersion; - public Permission(@NonNull String name, int minSdkVersion) { + /** + * The minimum SDK version for this permission to be optionally granted (when it is grantable). + */ + private final int mOptionalMinSdkVersion; + + public Permission(@NonNull String name, int minSdkVersion, int optionalMinSdkVersion) { mName = name; mMinSdkVersion = minSdkVersion; + mOptionalMinSdkVersion = optionalMinSdkVersion; } @NonNull @@ -54,33 +65,56 @@ public class Permission { return mMinSdkVersion; } + public int getOptionalMinSdkVersion() { + return mOptionalMinSdkVersion; + } + /** * Check whether this permission is available. * + * @param user the user to check for + * @param context the {@code Context} to retrieve system services + * * @return whether this permission is available */ - public boolean isAvailable() { - // Workaround to match the value 35+ for V+ in roles.xml before SDK finalization. - if (mMinSdkVersion >= 35) { - return SdkLevel.isAtLeastV(); - } else { - return Build.VERSION.SDK_INT >= mMinSdkVersion; + public boolean isAvailableAsUser(@NonNull UserHandle user, @NonNull Context context) { + if (Build.VERSION.SDK_INT >= mMinSdkVersion + // Workaround to match the value 35 for V in roles.xml before SDK finalization. + || (mMinSdkVersion == 35 && SdkLevel.isAtLeastV())) { + return true; + } + if (Build.VERSION.SDK_INT >= mOptionalMinSdkVersion) { + Context userContext = UserUtils.getUserContext(context, user); + PackageManager userPackageManager = userContext.getPackageManager(); + PermissionInfo permissionInfo; + try { + permissionInfo = userPackageManager.getPermissionInfo(mName, 0); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + return permissionInfo.getProtection() == PermissionInfo.PROTECTION_DANGEROUS + || (permissionInfo.getProtectionFlags() & PermissionInfo.PROTECTION_FLAG_ROLE) + == PermissionInfo.PROTECTION_FLAG_ROLE + || (permissionInfo.getProtectionFlags() & PermissionInfo.PROTECTION_FLAG_APPOP) + == PermissionInfo.PROTECTION_FLAG_APPOP; } + return false; } /** - * Return a new permission with the specified minimum SDK version, or this permission if it - * already has the same minimum SDK version. + * Return a new permission with the specified SDK versions, or this permission if it already has + * the same SDK versions. * * @param minSdkVersion the minimum SDK version - * @return a permission with the specified minimum SDK version + * @param optionalMinSdkVersion the optional minimum SDK version + * @return a permission with the specified SDK versions */ @NonNull - public Permission withMinSdkVersion(int minSdkVersion) { - if (mMinSdkVersion == minSdkVersion) { + public Permission withSdkVersions(int minSdkVersion, int optionalMinSdkVersion) { + if (mMinSdkVersion == minSdkVersion && mOptionalMinSdkVersion == optionalMinSdkVersion) { return this; } - return new Permission(mName, minSdkVersion); + return new Permission(mName, minSdkVersion, optionalMinSdkVersion); } @Override @@ -88,6 +122,7 @@ public class Permission { return "Permission{" + "mName='" + mName + '\'' + ", mMinSdkVersion=" + mMinSdkVersion + + ", mOptionalMinSdkVersion=" + mOptionalMinSdkVersion + '}'; } @@ -101,11 +136,12 @@ public class Permission { } Permission that = (Permission) object; return mMinSdkVersion == that.mMinSdkVersion + && mOptionalMinSdkVersion == that.mOptionalMinSdkVersion && mName.equals(that.mName); } @Override public int hashCode() { - return Objects.hash(mName, mMinSdkVersion); + return Objects.hash(mName, mMinSdkVersion, mOptionalMinSdkVersion); } } diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java b/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java index 8a15612b9..e788fdce1 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java @@ -61,16 +61,19 @@ public class Permissions { * Filter a list of permissions based on their SDK versions. * * @param permissions the list of permissions + * @param user the user to check for + * @param context the {@code Context} to retrieve system services * * @return the filtered list of permission names. */ @NonNull - public static List<String> filterBySdkVersion(@NonNull List<Permission> permissions) { + public static List<String> filterBySdkVersionAsUser(@NonNull List<Permission> permissions, + @NonNull UserHandle user, @NonNull Context context) { List<String> permissionNames = new ArrayList<>(); int permissionsSize = permissions.size(); for (int i = 0; i < permissionsSize; i++) { Permission permission = permissions.get(i); - if (!permission.isAvailable()) { + if (!permission.isAvailableAsUser(user, context)) { continue; } permissionNames.add(permission.getName()); diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java index 6c7eb7d9e..c3541c83b 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java @@ -17,9 +17,12 @@ package com.android.role.controller.model; import android.app.ActivityManager; +import android.app.admin.DevicePolicyManager; +import android.app.ecm.EnhancedConfirmationManager; import android.app.role.RoleManager; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.SharedLibraryInfo; @@ -27,6 +30,9 @@ import android.content.pm.Signature; import android.content.res.Resources; import android.os.Build; import android.os.UserHandle; +import android.os.UserManager; +import android.permission.flags.Flags; +import android.provider.Settings; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -128,6 +134,11 @@ public class Role { private final int mMinSdkVersion; /** + * Whether this role should only grant privileges when a role holder is actively added. + */ + private final boolean mOnlyGrantWhenAdded; + + /** * Whether this role should override user's choice about privileges when granting. */ private final boolean mOverrideUserWhenGranting; @@ -224,11 +235,11 @@ public class Role { @Nullable RoleBehavior behavior, @Nullable String defaultHoldersResourceName, @StringRes int descriptionResource, boolean exclusive, boolean fallBackToDefaultHolder, @StringRes int labelResource, int maxSdkVersion, int minSdkVersion, - boolean overrideUserWhenGranting, @StringRes int requestDescriptionResource, - @StringRes int requestTitleResource, boolean requestable, - @StringRes int searchKeywordsResource, @StringRes int shortLabelResource, - boolean showNone, boolean statik, boolean systemOnly, boolean visible, - @NonNull List<RequiredComponent> requiredComponents, + boolean onlyGrantWhenAdded, boolean overrideUserWhenGranting, + @StringRes int requestDescriptionResource, @StringRes int requestTitleResource, + boolean requestable, @StringRes int searchKeywordsResource, + @StringRes int shortLabelResource, boolean showNone, boolean statik, boolean systemOnly, + boolean visible, @NonNull List<RequiredComponent> requiredComponents, @NonNull List<Permission> permissions, @NonNull List<Permission> appOpPermissions, @NonNull List<AppOp> appOps, @NonNull List<PreferredActivity> preferredActivities, @Nullable String uiBehaviorName) { @@ -242,6 +253,7 @@ public class Role { mLabelResource = labelResource; mMaxSdkVersion = maxSdkVersion; mMinSdkVersion = minSdkVersion; + mOnlyGrantWhenAdded = onlyGrantWhenAdded; mOverrideUserWhenGranting = overrideUserWhenGranting; mRequestDescriptionResource = requestDescriptionResource; mRequestTitleResource = requestTitleResource; @@ -309,6 +321,13 @@ public class Role { } /** + * @see #mOnlyGrantWhenAdded + */ + public boolean shouldOnlyGrantWhenAdded() { + return mOnlyGrantWhenAdded; + } + + /** * @see #mOverrideUserWhenGranting */ public boolean shouldOverrideUserWhenGranting() { @@ -392,13 +411,10 @@ public class Role { * @return whether this role is available based on SDK version */ boolean isAvailableBySdkVersion() { - // Workaround to match the value 35+ for V+ in roles.xml before SDK finalization. - if (mMinSdkVersion >= 35) { - return SdkLevel.isAtLeastV(); - } else { - return Build.VERSION.SDK_INT >= mMinSdkVersion - && Build.VERSION.SDK_INT <= mMaxSdkVersion; - } + return (Build.VERSION.SDK_INT >= mMinSdkVersion + // Workaround to match the value 35 for V in roles.xml before SDK finalization. + || (mMinSdkVersion == 35 && SdkLevel.isAtLeastV())) + && Build.VERSION.SDK_INT <= mMaxSdkVersion; } public boolean isStatic() { @@ -416,10 +432,14 @@ public class Role { @NonNull public List<String> getDefaultHoldersAsUser(@NonNull UserHandle user, @NonNull Context context) { - if (mDefaultHoldersResourceName == null) { - if (mBehavior != null) { - return mBehavior.getDefaultHoldersAsUser(this, user, context); + if (mBehavior != null) { + List<String> defaultHolders = mBehavior.getDefaultHoldersAsUser(this, user, context); + if (defaultHolders != null) { + return defaultHolders; } + } + + if (mDefaultHoldersResourceName == null) { return Collections.emptyList(); } @@ -781,11 +801,12 @@ public class Role { public void grantAsUser(@NonNull String packageName, boolean dontKillApp, boolean overrideUser, @NonNull UserHandle user, @NonNull Context context) { boolean permissionOrAppOpChanged = Permissions.grantAsUser(packageName, - Permissions.filterBySdkVersion(mPermissions), + Permissions.filterBySdkVersionAsUser(mPermissions, user, context), SdkLevel.isAtLeastS() ? !mSystemOnly : true, overrideUser, true, false, false, user, context); - List<String> appOpPermissionsToGrant = Permissions.filterBySdkVersion(mAppOpPermissions); + List<String> appOpPermissionsToGrant = + Permissions.filterBySdkVersionAsUser(mAppOpPermissions, user, context); int appOpPermissionsSize = appOpPermissionsToGrant.size(); for (int i = 0; i < appOpPermissionsSize; i++) { String appOpPermission = appOpPermissionsToGrant.get(i); @@ -831,24 +852,27 @@ public class Role { List<String> otherRoleNames = userRoleManager.getHeldRolesFromController(packageName); otherRoleNames.remove(mName); - List<String> permissionsToRevoke = Permissions.filterBySdkVersion(mPermissions); + List<String> permissionsToRevoke = + Permissions.filterBySdkVersionAsUser(mPermissions, user, context); ArrayMap<String, Role> roles = Roles.get(context); int otherRoleNamesSize = otherRoleNames.size(); for (int i = 0; i < otherRoleNamesSize; i++) { String roleName = otherRoleNames.get(i); Role role = roles.get(roleName); - permissionsToRevoke.removeAll(Permissions.filterBySdkVersion(role.mPermissions)); + permissionsToRevoke.removeAll( + Permissions.filterBySdkVersionAsUser(role.mPermissions, user, context)); } boolean permissionOrAppOpChanged = Permissions.revokeAsUser(packageName, permissionsToRevoke, true, false, overrideSystemFixedPermissions, user, context); - List<String> appOpPermissionsToRevoke = Permissions.filterBySdkVersion(mAppOpPermissions); + List<String> appOpPermissionsToRevoke = Permissions.filterBySdkVersionAsUser( + mAppOpPermissions, user, context); for (int i = 0; i < otherRoleNamesSize; i++) { String roleName = otherRoleNames.get(i); Role role = roles.get(roleName); appOpPermissionsToRevoke.removeAll( - Permissions.filterBySdkVersion(role.mAppOpPermissions)); + Permissions.filterBySdkVersionAsUser(role.mAppOpPermissions, user, context)); } int appOpPermissionsSize = appOpPermissionsToRevoke.size(); for (int i = 0; i < appOpPermissionsSize; i++) { @@ -953,7 +977,7 @@ public class Role { * Check whether this role should be visible to user. * * @param user the user to check for - * @param context the `Context` to retrieve system services + * @param context the {@code Context} to retrieve system services * * @return whether this role should be visible to user */ @@ -983,6 +1007,76 @@ public class Role { return behavior.isApplicationVisibleAsUser(this, applicationInfo, user, context); } + /** + * Check whether this role is restricted and return the {@code Intent} for the restriction if it + * is. + * <p> + * If a role is restricted, it is implied that all applications are restricted for the role as + * well. + * + * @param user the user to check for + * @param context the {@code Context} to retrieve system services + * + * @return the {@code Intent} for the restriction if this role is restricted, or {@code null} + * otherwise. + */ + @Nullable + public Intent getRestrictionIntentAsUser(@NonNull UserHandle user, @NonNull Context context) { + if (SdkLevel.isAtLeastU() && mExclusive) { + UserManager userManager = context.getSystemService(UserManager.class); + if (userManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_DEFAULT_APPS, + user)) { + return new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS) + .putExtra(DevicePolicyManager.EXTRA_RESTRICTION, + UserManager.DISALLOW_CONFIG_DEFAULT_APPS); + } + } + return null; + } + + /** + * Check whether an application is restricted for this role and return the {@code Intent} for + * the restriction if it is. + * <p> + * If a role is restricted, it is implied that all applications are restricted for the role as + * well. + * + * @param applicationInfo the {@link ApplicationInfo} for the application + * @param user the user to check for + * @param context the {@code Context} to retrieve system services + * + * @return the {@code Intent} for the restriction if the application is restricted for this + * role, or {@code null} otherwise. + */ + @Nullable + public Intent getApplicationRestrictionIntentAsUser(@NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, @NonNull Context context) { + if (SdkLevel.isAtLeastV() && Flags.enhancedConfirmationModeApisEnabled()) { + Context userContext = UserUtils.getUserContext(context, user); + EnhancedConfirmationManager userEnhancedConfirmationManager = + userContext.getSystemService(EnhancedConfirmationManager.class); + String packageName = applicationInfo.packageName; + boolean isRestricted; + try { + isRestricted = userEnhancedConfirmationManager.isRestricted(packageName, mName); + } catch (PackageManager.NameNotFoundException e) { + Log.w(LOG_TAG, "Cannot check enhanced confirmation restriction for package: " + + packageName, e); + isRestricted = false; + } + if (isRestricted) { + try { + return userEnhancedConfirmationManager.createRestrictedSettingDialogIntent( + packageName, mName); + } catch (PackageManager.NameNotFoundException e) { + Log.w(LOG_TAG, "Cannot create enhanced confirmation restriction intent for" + + " package: " + packageName, e); + } + } + } + return getRestrictionIntentAsUser(user, context); + } + @Override public String toString() { return "Role{" @@ -996,6 +1090,7 @@ public class Role { + ", mLabelResource=" + mLabelResource + ", mMaxSdkVersion=" + mMaxSdkVersion + ", mMinSdkVersion=" + mMinSdkVersion + + ", mOnlyGrantWhenAdded=" + mOnlyGrantWhenAdded + ", mOverrideUserWhenGranting=" + mOverrideUserWhenGranting + ", mRequestDescriptionResource=" + mRequestDescriptionResource + ", mRequestTitleResource=" + mRequestTitleResource diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java index 4bc1873d5..3849a50e3 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java @@ -48,10 +48,10 @@ public interface RoleBehavior { /** * @see Role#getDefaultHolders(Context) */ - @NonNull + @Nullable default List<String> getDefaultHoldersAsUser(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { - return Collections.emptyList(); + return null; } /** diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java b/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java index cc2d102c8..ad9054727 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java @@ -24,6 +24,7 @@ import android.content.pm.PermissionInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.Build; +import android.os.Process; import android.permission.flags.Flags; import android.util.ArrayMap; import android.util.Log; @@ -92,6 +93,7 @@ public class RoleParser { private static final String ATTRIBUTE_LABEL = "label"; private static final String ATTRIBUTE_MAX_SDK_VERSION = "maxSdkVersion"; private static final String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; + private static final String ATTRIBUTE_ONLY_GRANT_WHEN_ADDED = "onlyGrantWhenAdded"; private static final String ATTRIBUTE_OVERRIDE_USER_WHEN_GRANTING = "overrideUserWhenGranting"; private static final String ATTRIBUTE_QUERY_FLAGS = "queryFlags"; private static final String ATTRIBUTE_REQUEST_TITLE = "requestTitle"; @@ -106,6 +108,7 @@ public class RoleParser { private static final String ATTRIBUTE_VISIBLE = "visible"; private static final String ATTRIBUTE_FLAGS = "flags"; private static final String ATTRIBUTE_MIN_TARGET_SDK_VERSION = "minTargetSdkVersion"; + private static final String ATTRIBUTE_OPTIONAL_MIN_SDK_VERSION = "optionalMinSdkVersion"; private static final String ATTRIBUTE_PERMISSION = "permission"; private static final String ATTRIBUTE_PROHIBITED = "prohibited"; private static final String ATTRIBUTE_VALUE = "value"; @@ -272,6 +275,8 @@ public class RoleParser { int minSdkVersion = getAttributeIntValue(parser, ATTRIBUTE_MIN_SDK_VERSION, Build.VERSION_CODES.BASE); + int optionalMinSdkVersion = getAttributeIntValue(parser, ATTRIBUTE_OPTIONAL_MIN_SDK_VERSION, + minSdkVersion); List<Permission> permissions = new ArrayList<>(); @@ -291,7 +296,10 @@ public class RoleParser { continue; } int mergedMinSdkVersion = Math.max(permission.getMinSdkVersion(), minSdkVersion); - permission = permission.withMinSdkVersion(mergedMinSdkVersion); + int mergedOptionalMinSdkVersion = Math.max(permission.getOptionalMinSdkVersion(), + optionalMinSdkVersion); + permission = permission.withSdkVersions(mergedMinSdkVersion, + mergedOptionalMinSdkVersion); validateNoDuplicateElement(permission, permissions, "permission"); permissions.add(permission); } else { @@ -313,7 +321,9 @@ public class RoleParser { } int minSdkVersion = getAttributeIntValue(parser, ATTRIBUTE_MIN_SDK_VERSION, Build.VERSION_CODES.BASE); - return new Permission(name, minSdkVersion); + int optionalMinSdkVersion = getAttributeIntValue(parser, ATTRIBUTE_OPTIONAL_MIN_SDK_VERSION, + minSdkVersion); + return new Permission(name, minSdkVersion, optionalMinSdkVersion); } @Nullable @@ -396,6 +406,9 @@ public class RoleParser { return null; } + boolean onlyGrantWhenAdded = getAttributeBooleanValue(parser, + ATTRIBUTE_ONLY_GRANT_WHEN_ADDED, false); + boolean overrideUserWhenGranting = getAttributeBooleanValue(parser, ATTRIBUTE_OVERRIDE_USER_WHEN_GRANTING, false); @@ -523,10 +536,11 @@ public class RoleParser { } return new Role(name, allowBypassingQualification, behavior, defaultHoldersResourceName, descriptionResource, exclusive, fallBackToDefaultHolder, labelResource, - maxSdkVersion, minSdkVersion, overrideUserWhenGranting, requestDescriptionResource, - requestTitleResource, requestable, searchKeywordsResource, shortLabelResource, - showNone, statik, systemOnly, visible, requiredComponents, permissions, - appOpPermissions, appOps, preferredActivities, uiBehaviorName); + maxSdkVersion, minSdkVersion, onlyGrantWhenAdded, overrideUserWhenGranting, + requestDescriptionResource, requestTitleResource, requestable, + searchKeywordsResource, shortLabelResource, showNone, statik, systemOnly, visible, + requiredComponents, permissions, appOpPermissions, appOps, preferredActivities, + uiBehaviorName); } @NonNull @@ -768,6 +782,8 @@ public class RoleParser { } int minSdkVersion = getAttributeIntValue(parser, ATTRIBUTE_MIN_SDK_VERSION, Build.VERSION_CODES.BASE); + int optionalMinSdkVersion = getAttributeIntValue(parser, + ATTRIBUTE_OPTIONAL_MIN_SDK_VERSION, minSdkVersion); List<Permission> permissionsInSet = permissionSet.getPermissions(); int permissionsInSetSize = permissionsInSet.size(); for (int permissionsInSetIndex = 0; @@ -775,7 +791,10 @@ public class RoleParser { Permission permission = permissionsInSet.get(permissionsInSetIndex); int mergedMinSdkVersion = Math.max(permission.getMinSdkVersion(), minSdkVersion); - permission = permission.withMinSdkVersion(mergedMinSdkVersion); + int mergedOptionalMinSdkVersion = Math.max( + permission.getOptionalMinSdkVersion(), optionalMinSdkVersion); + permission = permission.withSdkVersions(mergedMinSdkVersion, + mergedOptionalMinSdkVersion); // We do allow intersection between permission sets. permissions.add(permission); } @@ -1144,7 +1163,7 @@ public class RoleParser { } private void validatePermission(@NonNull Permission permission) { - if (!permission.isAvailable()) { + if (!permission.isAvailableAsUser(Process.myUserHandle(), mContext)) { return; } validatePermission(permission.getName(), true); @@ -1180,7 +1199,7 @@ public class RoleParser { } private void validateAppOpPermission(@NonNull Permission appOpPermission) { - if (!appOpPermission.isAvailable()) { + if (!appOpPermission.isAvailableAsUser(Process.myUserHandle(), mContext)) { return; } validateAppOpPermission(appOpPermission.getName()); diff --git a/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java index 2a6010c4d..bc7562c11 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java +++ b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java @@ -131,10 +131,12 @@ public class RoleControllerServiceImpl extends RoleControllerService { String packageName = currentPackageNames.get(currentPackageNamesIndex); if (role.isPackageQualifiedAsUser(packageName, mUser, mContext)) { - // We should not override user set or fixed permissions because we are only - // redoing the grant here. Otherwise, user won't be able to revoke permissions - // granted by role. - addRoleHolderInternal(role, packageName, false, false, true); + if (!role.shouldOnlyGrantWhenAdded()) { + // We should not override user set or fixed permissions because we are only + // redoing the grant here. Otherwise, user won't be able to revoke + // permissions granted by role. + addRoleHolderInternal(role, packageName, false, false, true); + } } else { Log.i(LOG_TAG, "Removing package that no longer qualifies for the role," + " package: " + packageName + ", role: " + roleName); diff --git a/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java b/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java index ac3b681a8..1f8e62556 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java +++ b/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java @@ -24,6 +24,8 @@ import android.os.UserManager; import androidx.annotation.NonNull; +import com.android.modules.utils.build.SdkLevel; + /** Utility class to deal with Android users. */ public final class UserUtils { @@ -37,7 +39,13 @@ public final class UserUtils { * @return whether the user is a profile */ public static boolean isProfile(@NonNull UserHandle user, @NonNull Context context) { - return isManagedProfile(user, context) || isCloneProfile(user, context); + if (SdkLevel.isAtLeastV()) { + Context userContext = getUserContext(context, user); + UserManager userUserManager = userContext.getSystemService(UserManager.class); + return userUserManager.isProfile(); + } else { + return isManagedProfile(user, context) || isCloneProfile(user, context); + } } /** diff --git a/PermissionController/role-controller/lint-baseline.xml b/PermissionController/role-controller/lint-baseline.xml index e7c119f3b..894dc1834 100644 --- a/PermissionController/role-controller/lint-baseline.xml +++ b/PermissionController/role-controller/lint-baseline.xml @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> -<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev"> +<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01"> <issue id="NewApi" message="Call requires API level 31 (current min is 30): `android.app.NotificationManager#setNotificationListenerAccessGranted`" - errorLine1=" notificationManager.setNotificationListenerAccessGranted(" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + errorLine1=" userNotificationManager.setNotificationListenerAccessGranted(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="packages/modules/Permission/PermissionController/role-controller/java/com/android/role/controller/util/NotificationUtils.java" - line="74" - column="33"/> + line="78" + column="37"/> </issue> </issues>
\ No newline at end of file diff --git a/PermissionController/src/com/android/permissioncontroller/Constants.java b/PermissionController/src/com/android/permissioncontroller/Constants.java index a063fb607..47ec9cabb 100644 --- a/PermissionController/src/com/android/permissioncontroller/Constants.java +++ b/PermissionController/src/com/android/permissioncontroller/Constants.java @@ -276,6 +276,12 @@ public class Constants { "com.android.permissioncontroller.extra.SESSION_ID"; /** + * Intent extra used to pass if the restriction dialog is triggered in-app. + */ + public static final String EXTRA_IS_ECM_IN_APP = + "com.android.permissincontroller.extra.IS_ECM_IN_APP"; + + /** * Intent extra used to pass privacy source details to safety center. */ public static final String EXTRA_PRIVACY_SOURCE = diff --git a/PermissionController/src/com/android/permissioncontroller/appops/data/model/PackageAppOpUsageModel.kt b/PermissionController/src/com/android/permissioncontroller/appops/data/model/PackageAppOpUsageModel.kt new file mode 100644 index 000000000..316f09463 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/appops/data/model/PackageAppOpUsageModel.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.appops.data.model + +/** + * Collection of app op usages for a package and user. App op usage represent private data access + * (i.e. location, contact access) by the app/package. + */ +data class PackageAppOpUsageModel( + val packageName: String, + val usages: List<AppOpUsageModel>, + val userId: Int +) { + /** Data class representing an app op and the recent access time by an app. */ + data class AppOpUsageModel( + val appOpName: String, + /** Milliseconds since the epoch */ + val lastAccessTimestampMillis: Long, + ) +} diff --git a/PermissionController/src/com/android/permissioncontroller/appops/data/repository/AppOpRepository.kt b/PermissionController/src/com/android/permissioncontroller/appops/data/repository/AppOpRepository.kt new file mode 100644 index 000000000..11ace12a2 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/appops/data/repository/AppOpRepository.kt @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.appops.data.repository + +import android.app.AppOpsManager +import android.app.Application +import android.content.pm.PackageManager +import android.os.UserHandle +import android.util.Log +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel.AppOpUsageModel +import com.android.permissioncontroller.permission.data.PackageBroadcastReceiver +import com.android.permissioncontroller.permission.data.repository.PermissionRepository +import com.android.permissioncontroller.permission.utils.PermissionMapping +import kotlin.concurrent.Volatile +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.flowOn + +/** + * This repository encapsulate app op data (i.e. app op usage, app op mode, historical ops etc.) + * exposed by [AppOpsManager]. + */ +interface AppOpRepository { + /** + * A flow/stream of package app ops, these app ops are processed to show the usage statistics in + * the privacy dashboard. + * + * @see AppOpsManager.getPackagesForOps + */ + val packageAppOpsUsages: Flow<List<PackageAppOpUsageModel>> + + companion object { + @Volatile private var instance: AppOpRepository? = null + + fun getInstance( + application: Application, + permissionRepository: PermissionRepository + ): AppOpRepository = + instance + ?: synchronized(this) { + AppOpRepositoryImpl(application, permissionRepository).also { instance = it } + } + } +} + +class AppOpRepositoryImpl( + application: Application, + private val permissionRepository: PermissionRepository, + private val dispatcher: CoroutineDispatcher = Dispatchers.Default, +) : AppOpRepository { + private val appOpsManager = + checkNotNull(application.getSystemService(AppOpsManager::class.java)) + private val packageManager = application.packageManager + + private val appOpNames = getPrivacyDashboardAppOpNames() + + override val packageAppOpsUsages by lazy { + callbackFlow { + send(getPackageOps()) + + // Suppress OnOpNotedListener lint error, startWatchingNoted is behind sdk check. + @SuppressWarnings("NewApi") + val callback = + object : + PackageManager.OnPermissionsChangedListener, + PackageBroadcastReceiver.PackageBroadcastListener, + AppOpsManager.OnOpActiveChangedListener, + AppOpsManager.OnOpNotedListener, + AppOpsManager.OnOpChangedListener { + override fun onPermissionsChanged(uid: Int) { + sendUpdate() + } + + override fun onOpChanged(op: String?, packageName: String?) { + sendUpdate() + } + + override fun onPackageUpdate(packageName: String) { + sendUpdate() + } + + override fun onOpActiveChanged( + op: String, + uid: Int, + packageName: String, + active: Boolean + ) { + sendUpdate() + } + + override fun onOpNoted( + op: String, + uid: Int, + packageName: String, + attributionTag: String?, + flags: Int, + result: Int + ) { + sendUpdate() + } + + fun sendUpdate() { + trySend(getPackageOps()) + } + } + + packageManager.addOnPermissionsChangeListener(callback) + PackageBroadcastReceiver.addAllCallback(callback) + appOpNames.forEach { opName -> + // TODO(b/262035952): We watch each active op individually as + // startWatchingActive only registers the callback if all ops are valid. + // Fix this behavior so if one op is invalid it doesn't affect the other ops. + try { + appOpsManager.startWatchingActive(arrayOf(opName), { it.run() }, callback) + } catch (ignored: IllegalArgumentException) { + // Older builds may not support all requested app ops. + } + + try { + appOpsManager.startWatchingMode(opName, /* all packages */ null, callback) + } catch (ignored: IllegalArgumentException) { + // Older builds may not support all requested app ops. + } + + if (SdkLevel.isAtLeastU()) { + try { + appOpsManager.startWatchingNoted(arrayOf(opName), callback) + } catch (ignored: IllegalArgumentException) { + // Older builds may not support all requested app ops. + } + } + } + + awaitClose { + packageManager.removeOnPermissionsChangeListener(callback) + PackageBroadcastReceiver.removeAllCallback(callback) + appOpsManager.stopWatchingActive(callback) + appOpsManager.stopWatchingMode(callback) + if (SdkLevel.isAtLeastU()) { + appOpsManager.stopWatchingNoted(callback) + } + } + } + .flowOn(dispatcher) + } + + private fun getPackageOps(): List<PackageAppOpUsageModel> { + return try { + appOpsManager.getPackagesForOps(appOpNames.toTypedArray()) + } catch (e: NullPointerException) { + Log.w(LOG_TAG, "App ops not recognized, app ops list: $appOpNames") + // Older builds may not support all requested app ops. + emptyList() + } + .map { packageOps -> + PackageAppOpUsageModel( + packageOps.packageName, + packageOps.ops.map { opEntry -> + AppOpUsageModel( + opEntry.opStr, + opEntry.getLastAccessTime(OPS_LAST_ACCESS_FLAGS) + ) + }, + UserHandle.getUserHandleForUid(packageOps.uid).identifier + ) + } + } + + private fun getPrivacyDashboardAppOpNames(): Set<String> { + val permissionGroups = permissionRepository.getPermissionGroupsForPrivacyDashboard() + val opNames = mutableSetOf<String>() + for (permissionGroup in permissionGroups) { + val permissionNames = + PermissionMapping.getPlatformPermissionNamesOfGroup(permissionGroup) + for (permissionName in permissionNames) { + val opName = AppOpsManager.permissionToOp(permissionName) ?: continue + opNames.add(opName) + } + } + + opNames.add(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE) + opNames.add(AppOpsManager.OPSTR_PHONE_CALL_CAMERA) + if (SdkLevel.isAtLeastT()) { + opNames.add(AppOpsManager.OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO) + } + return opNames + } + + companion object { + private const val LOG_TAG = "AppOpUsageRepository" + + private const val OPS_LAST_ACCESS_FLAGS = + AppOpsManager.OP_FLAG_SELF or + AppOpsManager.OP_FLAG_TRUSTED_PROXIED or + AppOpsManager.OP_FLAG_TRUSTED_PROXY + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/auto/DrivingDecisionReminderService.kt b/PermissionController/src/com/android/permissioncontroller/auto/DrivingDecisionReminderService.kt index 719ef33b5..0ee0e0d01 100644 --- a/PermissionController/src/com/android/permissioncontroller/auto/DrivingDecisionReminderService.kt +++ b/PermissionController/src/com/android/permissioncontroller/auto/DrivingDecisionReminderService.kt @@ -140,6 +140,14 @@ class DrivingDecisionReminderService : Service() { car.disconnect() } } + + fun cancelNotification(context: Context) { + val notificationManager = context.getSystemService(NotificationManager::class.java)!! + notificationManager.cancel( + DrivingDecisionReminderService::class.java.simpleName, + Constants.PERMISSION_DECISION_REMINDER_NOTIFICATION_ID + ) + } } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { diff --git a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt new file mode 100644 index 000000000..724dc1a8e --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.ecm + +import android.annotation.SuppressLint +import android.app.AlertDialog +import android.app.Dialog +import android.app.ecm.EnhancedConfirmationManager +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Build +import android.os.Bundle +import android.os.Process +import android.os.UserHandle +import android.permission.flags.Flags +import android.text.Html +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.widget.TextView +import androidx.annotation.ChecksSdkIntAtLeast +import androidx.annotation.Keep +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentActivity +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.Constants.EXTRA_IS_ECM_IN_APP +import com.android.permissioncontroller.R +import com.android.permissioncontroller.ecm.EnhancedConfirmationStatsLogUtils.DialogResult +import com.android.permissioncontroller.permission.utils.KotlinUtils +import com.android.permissioncontroller.permission.utils.PermissionMapping +import com.android.permissioncontroller.permission.utils.Utils +import com.android.role.controller.model.Roles + +@Keep +class EnhancedConfirmationDialogActivity : FragmentActivity() { + companion object { + private const val KEY_WAS_CLEAR_RESTRICTION_ALLOWED = "KEY_WAS_CLEAR_RESTRICTION_ALLOWED" + } + + private var wasClearRestrictionAllowed: Boolean = false + private var dialogResult: DialogResult = DialogResult.Cancelled + + @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM, codename = "VanillaIceCream") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (!SdkLevel.isAtLeastV() || !Flags.enhancedConfirmationModeApisEnabled()) { + finish() + return + } + if (savedInstanceState != null) { + wasClearRestrictionAllowed = + savedInstanceState.getBoolean(KEY_WAS_CLEAR_RESTRICTION_ALLOWED) + return + } + + val uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID) + val packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME) + val settingIdentifier = intent.getStringExtra(Intent.EXTRA_SUBJECT) + val isEcmInApp = intent.getBooleanExtra(EXTRA_IS_ECM_IN_APP, false) + + require(uid != Process.INVALID_UID) { "EXTRA_UID cannot be null or invalid" } + require(!packageName.isNullOrEmpty()) { "EXTRA_PACKAGE_NAME cannot be null or empty" } + require(!settingIdentifier.isNullOrEmpty()) { "EXTRA_SUBJECT cannot be null or empty" } + + wasClearRestrictionAllowed = + setClearRestrictionAllowed(packageName, UserHandle.getUserHandleForUid(uid)) + + val setting = Setting.fromIdentifier(this, settingIdentifier, isEcmInApp) + val dialogFragment = + EnhancedConfirmationDialogFragment.newInstance(setting.title, setting.message) + dialogFragment.show(supportFragmentManager, EnhancedConfirmationDialogFragment.TAG) + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putBoolean(KEY_WAS_CLEAR_RESTRICTION_ALLOWED, wasClearRestrictionAllowed) + } + + private fun setClearRestrictionAllowed(packageName: String, user: UserHandle): Boolean { + val userContext = createContextAsUser(user, 0) + val ecm = Utils.getSystemServiceSafe(userContext, EnhancedConfirmationManager::class.java) + try { + val wasClearRestrictionAllowed = ecm.isClearRestrictionAllowed(packageName) + ecm.setClearRestrictionAllowed(packageName) + return wasClearRestrictionAllowed + } catch (e: PackageManager.NameNotFoundException) { + throw IllegalArgumentException("unknown package: $packageName") + } + } + + private data class Setting(val title: String?, val message: CharSequence?) { + companion object { + fun fromIdentifier( + context: Context, + settingIdentifier: String, + isEcmInApp: Boolean + ): Setting { + val settingType = SettingType.fromIdentifier(context, settingIdentifier, isEcmInApp) + val label = + when (settingType) { + SettingType.PLATFORM_PERMISSION -> + KotlinUtils.getPermGroupLabel( + context, + PermissionMapping.getGroupOfPlatformPermission(settingIdentifier)!! + ) + SettingType.PLATFORM_PERMISSION_GROUP -> + KotlinUtils.getPermGroupLabel(context, settingIdentifier) + SettingType.ROLE -> + context.getString( + Roles.get(context)[settingIdentifier]!!.shortLabelResource + ) + SettingType.OTHER -> null + } + val url = + context.getString(R.string.help_url_action_disabled_by_restricted_settings) + return Setting( + title = settingType.titleRes?.let { context.getString(it, label) }, + message = + settingType.messageRes?.let { Html.fromHtml(context.getString(it, url), 0) } + ) + } + } + } + + private enum class SettingType(val titleRes: Int?, val messageRes: Int?) { + PLATFORM_PERMISSION( + R.string.enhanced_confirmation_dialog_title_permission, + R.string.enhanced_confirmation_dialog_desc_permission + ), + PLATFORM_PERMISSION_GROUP( + R.string.enhanced_confirmation_dialog_title_permission, + R.string.enhanced_confirmation_dialog_desc_permission + ), + ROLE( + R.string.enhanced_confirmation_dialog_title_role, + R.string.enhanced_confirmation_dialog_desc_role + ), + OTHER( + R.string.enhanced_confirmation_dialog_title_settings_default, + R.string.enhanced_confirmation_dialog_desc_settings_default + ); + + companion object { + fun fromIdentifier( + context: Context, + settingIdentifier: String, + isEcmInApp: Boolean + ): SettingType { + if (!isEcmInApp) return SettingType.OTHER + return when { + PermissionMapping.isRuntimePlatformPermission(settingIdentifier) && + PermissionMapping.getGroupOfPlatformPermission(settingIdentifier) != null -> + PLATFORM_PERMISSION + PermissionMapping.isPlatformPermissionGroup(settingIdentifier) -> + PLATFORM_PERMISSION_GROUP + settingIdentifier.startsWith("android.app.role.") && + Roles.get(context).containsKey(settingIdentifier) -> ROLE + else -> SettingType.OTHER + } + } + } + } + + private fun onDialogResult(dialogResult: DialogResult) { + this.dialogResult = dialogResult + setResult( + RESULT_OK, + Intent().apply { putExtra(Intent.EXTRA_RETURN_RESULT, dialogResult.statsLogValue) } + ) + finish() + } + + override fun onDestroy() { + super.onDestroy() + if (isFinishing) { + EnhancedConfirmationStatsLogUtils.logDialogResultReported( + uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID), + settingIdentifier = intent.getStringExtra(Intent.EXTRA_SUBJECT)!!, + firstShowForApp = !wasClearRestrictionAllowed, + dialogResult = dialogResult + ) + } + } + + class EnhancedConfirmationDialogFragment() : DialogFragment() { + companion object { + val TAG = EnhancedConfirmationDialogFragment::class.simpleName + private const val KEY_TITLE = "KEY_TITLE" + private const val KEY_MESSAGE = "KEY_MESSAGE" + + fun newInstance(title: String? = null, message: CharSequence? = null) = + EnhancedConfirmationDialogFragment().apply { + arguments = + Bundle().apply { + putString(KEY_TITLE, title) + putCharSequence(KEY_MESSAGE, message) + } + } + } + + private lateinit var dialogActivity: EnhancedConfirmationDialogActivity + + override fun onAttach(context: Context) { + super.onAttach(context) + dialogActivity = context as EnhancedConfirmationDialogActivity + } + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val title = arguments!!.getString(KEY_TITLE) + val message = arguments!!.getCharSequence(KEY_MESSAGE) + + return AlertDialog.Builder(dialogActivity) + .setView(createDialogView(dialogActivity, title, message)) + .setPositiveButton(R.string.enhanced_confirmation_dialog_ok) { _, _ -> + dialogActivity.onDialogResult(DialogResult.Okay) + } + .create() + } + + override fun onCancel(dialog: DialogInterface) { + super.onCancel(dialog) + dialogActivity.onDialogResult(DialogResult.Cancelled) + } + + @SuppressLint("InflateParams") + private fun createDialogView( + context: Context, + title: String?, + message: CharSequence? + ): View = + LayoutInflater.from(context) + .inflate(R.layout.enhanced_confirmation_dialog, null) + .apply { + title?.let { + requireViewById<TextView>(R.id.enhanced_confirmation_dialog_title).text = it + } + message?.let { + val descTextView = + requireViewById<TextView>(R.id.enhanced_confirmation_dialog_desc) + descTextView.text = it + descTextView.movementMethod = LinkMovementMethod.getInstance() + } + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationStatsLogUtils.kt b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationStatsLogUtils.kt new file mode 100644 index 000000000..218af9775 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationStatsLogUtils.kt @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.ecm + +import android.annotation.SuppressLint +import android.app.AppOpsManager +import android.app.ecm.EnhancedConfirmationManager +import android.content.Context +import android.content.pm.PackageManager +import android.os.UserHandle +import android.permission.flags.Flags +import android.util.Log +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.PermissionControllerStatsLog +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_CANCELLED +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_LEARN_MORE +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_OK +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_SUPPRESSED +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_UNSPECIFIED +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_APPOP +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_OTHER +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_PERMISSION +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_ROLE +import com.android.permissioncontroller.PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_UNSPECIFIED +import com.android.permissioncontroller.permission.utils.Utils + +/** + * Provides ECM-related metrics logging for PermissionController. + * + * @hide + */ +object EnhancedConfirmationStatsLogUtils { + private val LOG_TAG = EnhancedConfirmationStatsLogUtils::class.java.simpleName + + enum class DialogResult(val statsLogValue: Int) { + Unspecified(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_UNSPECIFIED), + Cancelled(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_CANCELLED), + LearnMore(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_LEARN_MORE), + Okay(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_OK), + Suppressed(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__RESULT__RESULT_SUPPRESSED) + } + + enum class SettingType(val statsLogValue: Int) { + Unspecified( + ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_UNSPECIFIED + ), + Appop(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_APPOP), + Permission( + ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_PERMISSION + ), + Role(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_ROLE), + Other(ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED__SETTING_TYPE__SETTING_TYPE_OTHER); + + companion object { + fun fromIdentifier(settingIdentifier: String): SettingType = + when { + settingIdentifier.startsWith("android:") -> Appop + settingIdentifier.startsWith("android.permission.") -> Permission + settingIdentifier.startsWith("android.permission-group.") -> Permission + settingIdentifier.startsWith("android.app.role.") -> Role + else -> Other + } + } + } + + fun logDialogResultReported( + uid: Int, + settingIdentifier: String, + firstShowForApp: Boolean, + dialogResult: DialogResult + ) { + if (!SdkLevel.isAtLeastV() || !Flags.enhancedConfirmationModeApisEnabled()) { + return + } + val settingType = SettingType.fromIdentifier(settingIdentifier) + + Log.v( + LOG_TAG, + "ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED: " + + "uid='$uid', " + + "settingIdentifier='$settingIdentifier', " + + "firstShowForApp='$firstShowForApp', " + + "settingType='$settingType', " + + "result='${dialogResult.statsLogValue}'" + ) + + PermissionControllerStatsLog.write( + PermissionControllerStatsLog.ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED, + uid, + settingIdentifier, + firstShowForApp, + settingType.statsLogValue, + dialogResult.statsLogValue + ) + } + + @SuppressLint("MissingPermission") + fun isPackageEcmRestricted(context: Context, packageName: String, uid: Int): Boolean { + if (!SdkLevel.isAtLeastV() || !Flags.enhancedConfirmationModeApisEnabled()) { + return false + } + val userContext = Utils.getUserContext(context, UserHandle.getUserHandleForUid(uid)) + val ecm = userContext.getSystemService(EnhancedConfirmationManager::class.java) + return try { + val arbitrarilyChosenRestrictedSetting = AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE + ecm?.isRestricted(packageName, arbitrarilyChosenRestrictedSetting) ?: false + } catch (e: PackageManager.NameNotFoundException) { + false + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt b/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt index 97dd3f43c..8e58d48d9 100644 --- a/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt +++ b/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt @@ -33,6 +33,7 @@ import androidx.wear.compose.foundation.lazy.ScalingLazyListState import androidx.wear.compose.material.CircularProgressIndicator import com.android.permissioncontroller.permission.ui.wear.elements.AlertDialog import com.android.permissioncontroller.permission.ui.wear.elements.SingleButtonAlertDialog +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme @Composable fun WearConfirmationScreen(viewModel: WearConfirmationActivityViewModel) { @@ -77,5 +78,7 @@ fun WearConfirmationScreen(viewModel: WearConfirmationActivityViewModel) { } fun createView(activity: Activity, viewModel: WearConfirmationActivityViewModel): View { - return ComposeView(activity).apply { setContent { WearConfirmationScreen(viewModel) } } + return ComposeView(activity).apply { + setContent { WearPermissionTheme { WearConfirmationScreen(viewModel) } } + } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/DataRepository.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/DataRepository.kt index 9a826deb1..c69bb54fd 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/DataRepository.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/DataRepository.kt @@ -21,6 +21,7 @@ import android.content.ComponentCallbacks2 import android.content.res.Configuration import androidx.annotation.GuardedBy import androidx.annotation.MainThread +import com.android.modules.utils.build.SdkLevel import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.utils.ContextCompat import com.android.permissioncontroller.permission.utils.KotlinUtils @@ -77,10 +78,7 @@ abstract class DataRepository<K, V : DataRepository.InactiveTimekeeper> : Compon @MainThread protected abstract fun newValue(key: K): V /** - * Remove LiveData objects with no observer based on the severity of the memory pressure. If - * this is a low RAM device, eject all caches always, including upon the UI closing. - * - * @param level The severity of the current memory pressure + * Remove LiveData objects with no observer. */ override fun onTrimMemory(level: Int) { if (isLowMemoryDevice) { @@ -88,22 +86,33 @@ abstract class DataRepository<K, V : DataRepository.InactiveTimekeeper> : Compon return } + if (SdkLevel.isAtLeastU() && level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { + // On UDC+ TRIM_MEMORY_BACKGROUND may be the last callback an app will receive + // before it's frozen. + trimInactiveData(TIME_THRESHOLD_ALL_NANOS) + return + } + trimInactiveData( threshold = when (level) { ComponentCallbacks2.TRIM_MEMORY_BACKGROUND -> TIME_THRESHOLD_LAX_NANOS - ComponentCallbacks2.TRIM_MEMORY_MODERATE -> TIME_THRESHOLD_TIGHT_NANOS - ComponentCallbacks2.TRIM_MEMORY_COMPLETE -> TIME_THRESHOLD_ALL_NANOS - ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE -> TIME_THRESHOLD_LAX_NANOS - ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW -> TIME_THRESHOLD_TIGHT_NANOS - ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> TIME_THRESHOLD_ALL_NANOS + // Allow handling for trim levels that are deprecated in newer API versions + // but are still supported on older devices that this code ships to. + @Suppress("DEPRECATION") ComponentCallbacks2.TRIM_MEMORY_MODERATE -> TIME_THRESHOLD_TIGHT_NANOS + @Suppress("DEPRECATION") ComponentCallbacks2.TRIM_MEMORY_COMPLETE -> TIME_THRESHOLD_ALL_NANOS + @Suppress("DEPRECATION") ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE -> TIME_THRESHOLD_LAX_NANOS + @Suppress("DEPRECATION") ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW -> TIME_THRESHOLD_TIGHT_NANOS + @Suppress("DEPRECATION") ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> TIME_THRESHOLD_ALL_NANOS else -> return } ) } + // Allow handling for trim levels that are deprecated in newer API versions + // but are still supported on older devices that this code ships to. override fun onLowMemory() { - onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE) + onTrimMemory(@Suppress("DEPRECATION") ComponentCallbacks2.TRIM_MEMORY_COMPLETE) } override fun onConfigurationChanged(newConfig: Configuration) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/LightPackageInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/LightPackageInfoLiveData.kt index ef0a36583..ac3f670ec 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/LightPackageInfoLiveData.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/LightPackageInfoLiveData.kt @@ -30,8 +30,8 @@ import com.android.modules.utils.build.SdkLevel import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import com.android.permissioncontroller.permission.utils.ContextCompat -import com.android.permissioncontroller.permission.utils.MultiDeviceUtils.isPermissionDeviceAware import com.android.permissioncontroller.permission.utils.Utils +import com.android.permissioncontroller.permission.utils.v35.MultiDeviceUtils.isPermissionDeviceAware import kotlinx.coroutines.Job /** @@ -233,7 +233,7 @@ private constructor( val deviceContext = ContextCompat.createDeviceContext(app, deviceId) for ((idx, permName) in requestedPermissions.withIndex()) { - if (isPermissionDeviceAware(permName)) { + if (isPermissionDeviceAware(deviceContext, deviceId, permName)) { val result = deviceContext.checkPermission(permName, -1, uid) if (result == PackageManager.PERMISSION_GRANTED) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/PackageBroadcastReceiver.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/PackageBroadcastReceiver.kt index 09a7bb1e4..02429e294 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/PackageBroadcastReceiver.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/PackageBroadcastReceiver.kt @@ -25,6 +25,7 @@ import com.android.modules.utils.build.SdkLevel import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.data.v34.LightInstallSourceInfoLiveData import com.android.permissioncontroller.permission.data.v34.SafetyLabelInfoLiveData +import com.android.permissioncontroller.permission.data.v35.PackagePermissionsExternalDeviceLiveData import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -162,6 +163,7 @@ object PackageBroadcastReceiver : BroadcastReceiver() { LightPackageInfoLiveData.invalidateAllForPackage(packageName) PermStateLiveData.invalidateAllForPackage(packageName) PackagePermissionsLiveData.invalidateAllForPackage(packageName) + PackagePermissionsExternalDeviceLiveData.invalidateAllForPackage(packageName) HibernationSettingStateLiveData.invalidateAllForPackage(packageName) LightAppPermGroupLiveData.invalidateAllForPackage(packageName) AppPermGroupUiInfoLiveData.invalidateAllForPackage(packageName) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/PermGroupsPackagesUiInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/PermGroupsPackagesUiInfoLiveData.kt index cc5f156ce..0ebfcd3d7 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/PermGroupsPackagesUiInfoLiveData.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/PermGroupsPackagesUiInfoLiveData.kt @@ -21,6 +21,7 @@ import android.app.role.RoleManager import android.os.Handler import android.os.Looper import android.os.UserHandle +import android.os.UserManager import androidx.lifecycle.LiveData import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo @@ -62,6 +63,8 @@ class PermGroupsPackagesUiInfoLiveData( private val allPackageData = mutableMapOf<String, PermGroupPackagesUiInfo?>() private lateinit var groupNames: List<String> + private val userManager = + Utils.getSystemServiceSafe(app.applicationContext, UserManager::class.java) init { addSource(groupNamesLiveData) { @@ -91,12 +94,22 @@ class PermGroupsPackagesUiInfoLiveData( var grantedSystem = 0 var userInteractedSystem = 0 var firstGrantedSystemPackageName: String? = null + val showInSettingsByUsers = HashMap<UserHandle, Boolean>() for ((packageUserPair, appPermGroup) in appPermGroups) { if (!appPermGroup.shouldShow) { continue } + if (!showInSettingsByUsers.containsKey(packageUserPair.second)) { + showInSettingsByUsers[packageUserPair.second] = + Utils.shouldShowInSettings(packageUserPair.second, userManager) + } + + if (showInSettingsByUsers[packageUserPair.second] == false) { + continue + } + if (appPermGroup.isSystem) { if (isGranted(appPermGroup.permGrantState)) { if (grantedSystem == 0) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/repository/PermissionRepository.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/repository/PermissionRepository.kt new file mode 100644 index 000000000..a455783b4 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/repository/PermissionRepository.kt @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.data.repository + +import android.app.Application +import android.content.Context +import android.content.pm.PackageItemInfo +import android.content.pm.PackageManager +import android.os.UserHandle +import android.text.TextUtils +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.permission.utils.PermissionMapping +import kotlin.concurrent.Volatile +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * This repository encapsulates permission data (i.e. permission or permission group definitions, + * package permission states etc.) exposed by [android.permission.PermissionManager] and + * [PackageManager]. + */ +interface PermissionRepository { + /** + * Gets the flags associated with a permission. + * + * @see PackageManager.getPermissionFlags + */ + suspend fun getPermissionFlags( + permissionName: String, + packageName: String, + user: UserHandle + ): Int + + /** + * Gets a permission group label for a given permission group. + * + * @see PackageManager.getPermissionGroupInfo + * @see PackageItemInfo.loadSafeLabel + */ + suspend fun getPermissionGroupLabel(context: Context, groupName: String): CharSequence + + /** Gets a list of permission group to be shown in the privacy dashboard. */ + fun getPermissionGroupsForPrivacyDashboard(): List<String> + + companion object { + @Volatile private var instance: PermissionRepository? = null + + fun getInstance(application: Application): PermissionRepository = + instance + ?: synchronized(this) { + PermissionRepositoryImpl(application).also { instance = it } + } + } +} + +class PermissionRepositoryImpl( + application: Application, + private val dispatcher: CoroutineDispatcher = Dispatchers.Default, +) : PermissionRepository { + private val packageManager = application.packageManager + + override suspend fun getPermissionFlags( + permissionName: String, + packageName: String, + user: UserHandle + ): Int = + withContext(dispatcher) { + packageManager.getPermissionFlags(permissionName, packageName, user) + } + + /** + * Gets a permission group's label from the system. + * + * @param context The context from which to get the label + * @param groupName The name of the permission group whose label we want + * @return The permission group's label, or the group name, if the group is invalid + */ + override suspend fun getPermissionGroupLabel( + context: Context, + groupName: String + ): CharSequence = + withContext(dispatcher) { + val groupInfo = getPermissionGroupInfo(groupName, context) + groupInfo?.loadSafeLabel( + context.packageManager, + 0f, + TextUtils.SAFE_STRING_FLAG_FIRST_LINE or TextUtils.SAFE_STRING_FLAG_TRIM + ) + ?: groupName + } + + /** + * Get the [PackageItemInfo] for the given permission group. + * + * @param groupName the group + * @param context the `Context` to retrieve `PackageManager` + * @return The info of permission group or null if the group does not have runtime permissions. + */ + private fun getPermissionGroupInfo(groupName: String, context: Context): PackageItemInfo? { + return try { + context.packageManager.getPermissionGroupInfo(groupName, 0) + } catch (e: PackageManager.NameNotFoundException) { + null + } + ?: try { + context.packageManager.getPermissionInfo(groupName, 0) + } catch (e: PackageManager.NameNotFoundException) { + null + } + } + + override fun getPermissionGroupsForPrivacyDashboard(): List<String> { + return if (SdkLevel.isAtLeastT()) { + PermissionMapping.getPlatformPermissionGroups().filter { + it != android.Manifest.permission_group.NOTIFICATIONS + } + } else { + PermissionMapping.getPlatformPermissionGroups() + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/v35/PackagePermissionsExternalDeviceLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/v35/PackagePermissionsExternalDeviceLiveData.kt new file mode 100644 index 000000000..66267d6a3 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/v35/PackagePermissionsExternalDeviceLiveData.kt @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.data.v35 + +import android.app.Application +import android.companion.virtual.VirtualDeviceManager +import android.content.pm.PackageManager +import android.os.Build +import android.os.UserHandle +import android.permission.PermissionManager +import android.permission.PermissionManager.PermissionState +import androidx.annotation.RequiresApi +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.PermissionControllerApplication +import com.android.permissioncontroller.permission.data.DataRepositoryForPackage +import com.android.permissioncontroller.permission.data.SmartAsyncMediatorLiveData +import com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo +import com.android.permissioncontroller.permission.utils.PermissionMapping +import kotlinx.coroutines.Job + +/** + * LiveData that loads all the external device permissions per package. The permissions will be + * loaded only if the package has requested the permission. This live data produces the list of + * {@link ExternalDeviceGrantInfo} that has group name to which permission belongs to, grant state + * and persistentDeviceId + * + * @param app The current Application + * @param packageName The name of the package + * @param user The user for whom the packageInfo will be defined + */ +class PackagePermissionsExternalDeviceLiveData +private constructor(private val app: Application, val packageName: String, val user: UserHandle) : + SmartAsyncMediatorLiveData< + List<PackagePermissionsExternalDeviceLiveData.ExternalDeviceGrantInfo> + >() { + private val permissionManager = app.getSystemService(PermissionManager::class.java)!! + + data class ExternalDeviceGrantInfo( + val groupName: String, + val permGrantState: AppPermGroupUiInfo.PermGrantState, + val persistentDeviceId: String + ) + + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + override suspend fun loadDataAndPostValue(job: Job) { + if (!SdkLevel.isAtLeastV()) { + return + } + val virtualDeviceManager = app.getSystemService(VirtualDeviceManager::class.java)!! + val externalDeviceGrantInfoList = + virtualDeviceManager.allPersistentDeviceIds + .map { getVirtualDeviceGrantInfoList(it) } + .toList() + .flatten() + postValue(externalDeviceGrantInfoList) + } + + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + private fun getVirtualDeviceGrantInfoList( + persistentDeviceId: String + ): List<ExternalDeviceGrantInfo> { + val permissionState = + permissionManager.getAllPermissionStates(packageName, persistentDeviceId) + return permissionState.mapNotNull { (permissionName, permissionState) -> + PermissionMapping.getGroupOfPlatformPermission(permissionName)?.let { groupName -> + val grantState = getGrantState(permissionState) + ExternalDeviceGrantInfo(groupName, grantState, persistentDeviceId) + } + } + } + + /** + * This method returns the GrantState for currently supported virtual device permissions + * (Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO). + * + * TODO: b/328841671 (Unite this with PermGroupUiInfoLiveData#getGrantedIncludingBackground) + */ + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + private fun getGrantState(permissionState: PermissionState): AppPermGroupUiInfo.PermGrantState = + if (permissionState.isGranted) { + AppPermGroupUiInfo.PermGrantState.PERMS_ALLOWED_FOREGROUND_ONLY + } else if (permissionState.flags and PackageManager.FLAG_PERMISSION_ONE_TIME != 0) { + AppPermGroupUiInfo.PermGrantState.PERMS_ASK + } else { + AppPermGroupUiInfo.PermGrantState.PERMS_DENIED + } + + companion object : + DataRepositoryForPackage< + Pair<String, UserHandle>, PackagePermissionsExternalDeviceLiveData + >() { + override fun newValue( + key: Pair<String, UserHandle> + ): PackagePermissionsExternalDeviceLiveData { + return PackagePermissionsExternalDeviceLiveData( + PermissionControllerApplication.get(), + key.first, + key.second + ) + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/domain/model/PackagePermissionGroupUsageModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/domain/model/PackagePermissionGroupUsageModel.kt new file mode 100644 index 000000000..ef4602768 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/domain/model/PackagePermissionGroupUsageModel.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.domain.model + +/** This data class stores all data accesses (derived from app ops) for a package and user. */ +data class PackagePermissionGroupUsageModel( + val packageName: String, + /** Permission group and recent usage time in milliseconds since the epoch */ + val usages: Map<String, Long>, + val userId: Int +) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/domain/model/PermissionGroupUsageModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/domain/model/PermissionGroupUsageModel.kt new file mode 100644 index 000000000..5bb3bb3f0 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/domain/model/PermissionGroupUsageModel.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.domain.model + +/** Represents the private data access protected by the permission group. */ +data class PermissionGroupUsageModel( + val permissionGroup: String, + /** Milliseconds since the epoch */ + val lastAccessTimestampMillis: Long, + /** + * Represents whether the permission group is highly visible to the user. Permission groups for + * non system apps are always considered user sensitive and the usages are always shown in the + * dashboard. If the permission group is not user sensitive (in case of system apps), those + * usages are only shown when user click "Show system" button. + */ + val isUserSensitive: Boolean, +) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/GetPermissionGroupUsageUseCase.kt b/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/GetPermissionGroupUsageUseCase.kt new file mode 100644 index 000000000..8ec9bb9b6 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/GetPermissionGroupUsageUseCase.kt @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.domain.usecase + +import android.Manifest +import android.app.Application +import android.content.pm.ApplicationInfo +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import android.os.UserHandle +import android.util.Log +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel +import com.android.permissioncontroller.appops.data.repository.AppOpRepository +import com.android.permissioncontroller.permission.data.repository.PermissionRepository +import com.android.permissioncontroller.permission.domain.model.PackagePermissionGroupUsageModel +import com.android.permissioncontroller.permission.domain.model.PermissionGroupUsageModel +import com.android.permissioncontroller.permission.utils.PermissionMapping +import com.android.permissioncontroller.pm.data.repository.PackageRepository +import com.android.permissioncontroller.role.data.repository.RoleRepository +import com.android.permissioncontroller.user.data.repository.UserRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +/** + * This use case read app ops data and transform that data to show the private data access by apps + * in privacy dashboard. + */ +class GetPermissionGroupUsageUseCase( + private val packageRepository: PackageRepository, + private val permissionRepository: PermissionRepository, + private val appOpRepository: AppOpRepository, + private val roleRepository: RoleRepository, + private val userRepository: UserRepository, +) { + /** + * Returns a flow (i.e. a stream) of permission group usages (i.e. the private data accesses) + * for privacy dashboard page. + */ + operator fun invoke(): Flow<List<PermissionGroupUsageModel>> { + return appOpRepository.packageAppOpsUsages.map { packagesOps -> + val exemptedPackages = roleRepository.getExemptedPackages() + val currentUsers = userRepository.getUserProfilesIncludingCurrentUser() + + packagesOps + .mapToPermissionGroups() + .filter { it.userId in currentUsers } + .filter { it.packageName !in exemptedPackages } + .filterQuietProfilesIfNeeded(currentUsers) + .filterNonRequestedOps() + .buildPermissionGroupUsageModels() + } + } + + /** filter private space usages if needed. */ + private suspend fun List<PackagePermissionGroupUsageModel>.filterQuietProfilesIfNeeded( + currentUsers: List<Int> + ): List<PackagePermissionGroupUsageModel> { + if (!SdkLevel.isAtLeastV()) { + return this + } + val usersQuietModeEnabledMap = + currentUsers.associateWith { userId -> userRepository.isQuietModeEnabled(userId) } + val usersShouldShowInQuietModeMap = + currentUsers.associateWith { userId -> userRepository.shouldShowInQuietMode(userId) } + return filter { + val isQuietModeEnabled = checkNotNull(usersQuietModeEnabledMap[it.userId]) + val shouldShowInQuietMode = checkNotNull(usersShouldShowInQuietModeMap[it.userId]) + !isQuietModeEnabled || shouldShowInQuietMode + } + } + + private fun List<PackageAppOpUsageModel>.mapToPermissionGroups(): + List<PackagePermissionGroupUsageModel> { + return mapNotNull { packageOps -> + val permissionGroupUsages = + packageOps.usages + .mapNotNull { + val permissionGroup = + PermissionMapping.getPlatformPermissionGroupForOp(it.appOpName) + if (permissionGroup != null) { + Pair(permissionGroup, it.lastAccessTimestampMillis) + } else { + Log.w(LOG_TAG, "No permission group found for op: ${it.appOpName}") + null + } + } + .groupBy { it.first } // group by permission group name + .map { it -> // keep permission group and recent usage time + it.key to it.value.map { it.second }.maxOf { it } + } + .toMap() + + if (permissionGroupUsages.isNotEmpty()) { + PackagePermissionGroupUsageModel( + packageOps.packageName, + permissionGroupUsages, + packageOps.userId + ) + } else { + null + } + } + } + + /** Filter Ops where the corresponding permission group is no longer requested by the package */ + private suspend fun List<PackagePermissionGroupUsageModel>.filterNonRequestedOps(): + List<PackagePermissionGroupUsageModel> { + return mapNotNull { pkgOps -> + val userHandle = UserHandle.of(pkgOps.userId) + val packageInfo = packageRepository.getPackageInfo(pkgOps.packageName, userHandle) + val filteredOps = + pkgOps.usages.filter { permissionGroupUsage -> + packageInfo?.requestedPermissions?.any { permission -> + permissionGroupUsage.key == + PermissionMapping.getGroupOfPlatformPermission(permission) + } + ?: false + } + if (filteredOps.isNotEmpty()) { + PackagePermissionGroupUsageModel(pkgOps.packageName, filteredOps, pkgOps.userId) + } else { + null + } + } + } + + private suspend fun List<PackagePermissionGroupUsageModel>.buildPermissionGroupUsageModels(): + List<PermissionGroupUsageModel> { + return flatMap { pkgOps -> + pkgOps.usages.map { permGroupLastAccessTimeEntry -> + PermissionGroupUsageModel( + permGroupLastAccessTimeEntry.key, + permGroupLastAccessTimeEntry.value, + isPermissionGroupUserSensitive( + pkgOps.packageName, + permGroupLastAccessTimeEntry.key, + pkgOps.userId + ) + ) + } + } + } + + /** + * Determines if an app's permission group is user-sensitive. if the permission group is not + * user sensitive then its only shown when user choose `Show system` option + */ + private suspend fun isPermissionGroupUserSensitive( + packageName: String, + permissionGroup: String, + userId: Int + ): Boolean { + if (isTelecomPackage(packageName, permissionGroup)) { + return false + } + val userHandle = UserHandle.of(userId) + val packageInfo = packageRepository.getPackageInfo(packageName, userHandle) ?: return false + // if not a system app, the permission group must be user sensitive + if (packageInfo.applicationFlags and ApplicationInfo.FLAG_SYSTEM == 0) { + return true + } + + packageInfo.requestedPermissions.forEachIndexed { index, permissionName -> + if (PermissionMapping.getGroupOfPlatformPermission(permissionName) == permissionGroup) { + val permFlags = + permissionRepository.getPermissionFlags(permissionName, packageName, userHandle) + val packageFlags = packageInfo.requestedPermissionsFlags[index] + val isPermissionGranted = + packageFlags and PackageInfo.REQUESTED_PERMISSION_GRANTED != 0 && + permFlags and PackageManager.FLAG_PERMISSION_REVOKED_COMPAT == 0 + if (isPermissionUserSensitive(isPermissionGranted, permFlags)) { + return true + } + } + } + return false + } + + private fun isTelecomPackage(packageName: String, permissionGroup: String): Boolean { + return packageName == TELECOM_PACKAGE && + (permissionGroup == Manifest.permission_group.CAMERA || + permissionGroup == Manifest.permission_group.MICROPHONE) + } + + private fun isPermissionUserSensitive( + isPermissionGranted: Boolean, + permissionFlags: Int + ): Boolean { + return if (isPermissionGranted) { + permissionFlags and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED != 0 + } else { + permissionFlags and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED != 0 + } + } + + companion object { + private val LOG_TAG = GetPermissionGroupUsageUseCase::class.java.simpleName + private const val TELECOM_PACKAGE = "com.android.server.telecom" + + fun create(app: Application): GetPermissionGroupUsageUseCase { + val permissionRepository = PermissionRepository.getInstance(app) + val userRepository = UserRepository.getInstance(app) + val packageRepository = PackageRepository.getInstance(app) + val roleRepository = RoleRepository.getInstance(app) + val appOpRepository = AppOpRepository.getInstance(app, permissionRepository) + + return GetPermissionGroupUsageUseCase( + packageRepository, + permissionRepository, + appOpRepository, + roleRepository, + userRepository + ) + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt b/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt index 8e1721219..24cff7307 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt @@ -31,6 +31,7 @@ import com.android.permissioncontroller.DumpableLog import com.android.permissioncontroller.PermissionControllerStatsLog import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_UNUSED_APP_PERMISSION_REVOKED +import com.android.permissioncontroller.ecm.EnhancedConfirmationStatsLogUtils import com.android.permissioncontroller.hibernation.getUnusedThresholdMs import com.android.permissioncontroller.permission.data.AutoRevokedPackagesLiveData import com.android.permissioncontroller.permission.data.LightAppPermGroupLiveData @@ -199,6 +200,12 @@ suspend fun revokeAppPermissions( val uid = group.packageInfo.uid for (permName in revocablePermissions) { + val isPackageRestrictedByEnhancedConfirmation = + EnhancedConfirmationStatsLogUtils.isPackageEcmRestricted( + context, + packageName, + uid + ) PermissionControllerStatsLog.write( PERMISSION_GRANT_REQUEST_RESULT_REPORTED, sessionId, @@ -207,7 +214,8 @@ suspend fun revokeAppPermissions( permName, false, SERVER_LOG_ID, - /* permission_rationale_shown = */ false + /* permission_rationale_shown = */ false, + isPackageRestrictedByEnhancedConfirmation ) } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java b/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java index 3e7ebfec0..34a7337d0 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.java @@ -56,6 +56,7 @@ import androidx.annotation.RequiresApi; import com.android.permissioncontroller.PermissionControllerProto.PermissionControllerDumpProto; import com.android.permissioncontroller.PermissionControllerStatsLog; +import com.android.permissioncontroller.ecm.EnhancedConfirmationStatsLogUtils; import com.android.permissioncontroller.permission.model.AppPermissionGroup; import com.android.permissioncontroller.permission.model.AppPermissions; import com.android.permissioncontroller.permission.model.Permission; @@ -742,11 +743,14 @@ public final class PermissionControllerServiceImpl extends PermissionControllerL "Permission grant result requestId=" + requestId + " callingUid=" + uid + " callingPackage=" + packageName + " permission=" + permName + " isImplicit=false" + " result=" + r); - + boolean isPackageRestrictedByEnhancedConfirmation = + EnhancedConfirmationStatsLogUtils.INSTANCE.isPackageEcmRestricted(this, + packageName, uid); PermissionControllerStatsLog.write( PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED, requestId, uid, packageName, permName, false, r, - /* permission_rationale_shown = */ false); + /* permission_rationale_shown = */ false, + isPackageRestrictedByEnhancedConfirmation); } } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/v33/SafetyCenterQsTileService.kt b/PermissionController/src/com/android/permissioncontroller/permission/service/v33/SafetyCenterQsTileService.kt index 6ffd894ce..a69b78a06 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/service/v33/SafetyCenterQsTileService.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/service/v33/SafetyCenterQsTileService.kt @@ -27,6 +27,7 @@ import android.provider.DeviceConfig import android.safetycenter.SafetyCenterManager import android.service.quicksettings.Tile import android.service.quicksettings.TileService +import android.text.TextUtils import android.util.Log import com.android.modules.utils.build.SdkLevel import com.android.permissioncontroller.R @@ -68,6 +69,7 @@ class SafetyCenterQsTileService : TileService() { qsTile.label = getString(R.string.safety_privacy_qs_tile_title) qsTile.subtitle = getString(R.string.safety_privacy_qs_tile_subtitle) + qsTile.contentDescription = TextUtils.concat(qsTile.label, ", ", qsTile.subtitle) qsTile.state = Tile.STATE_ACTIVE qsTile.updateTile() } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java index cb7c4f6ee..7c7de5716 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java @@ -23,6 +23,7 @@ import static android.Manifest.permission_group.READ_MEDIA_VISUAL; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; +import static com.android.permissioncontroller.Constants.EXTRA_IS_ECM_IN_APP; import static com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler.CANCELED; import static com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler.DENIED; import static com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler.DENIED_DO_NOT_ASK_AGAIN; @@ -34,12 +35,17 @@ import static com.android.permissioncontroller.permission.ui.GrantPermissionsVie import static com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler.LINKED_TO_PERMISSION_RATIONALE; import static com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler.LINKED_TO_SETTINGS; import static com.android.permissioncontroller.permission.ui.model.GrantPermissionsViewModel.APP_PERMISSION_REQUEST_CODE; +import static com.android.permissioncontroller.permission.ui.model.GrantPermissionsViewModel.ECM_REQUEST_CODE; import static com.android.permissioncontroller.permission.ui.model.GrantPermissionsViewModel.PHOTO_PICKER_REQUEST_CODE; import static com.android.permissioncontroller.permission.utils.Utils.getRequestMessage; +import static com.android.permissioncontroller.permission.utils.v35.MultiDeviceUtils.isDeviceAwarePermissionSupported; import android.Manifest; +import android.annotation.SuppressLint; import android.app.Activity; import android.app.KeyguardManager; +import android.app.ecm.EnhancedConfirmationManager; +import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageItemInfo; @@ -49,6 +55,8 @@ import android.graphics.drawable.Icon; import android.os.Build; import android.os.Bundle; import android.os.Process; +import android.os.UserHandle; +import android.permission.flags.Flags; import android.text.Annotation; import android.text.SpannableString; import android.text.Spanned; @@ -56,13 +64,16 @@ import android.text.style.ClickableSpan; import android.util.ArraySet; import android.util.Log; import android.util.Pair; -import android.view.MotionEvent; +import android.view.KeyEvent; import android.view.View; import android.view.View.OnAttachStateChangeListener; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.ChecksSdkIntAtLeast; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -72,6 +83,7 @@ import androidx.core.util.Preconditions; import com.android.modules.utils.build.SdkLevel; import com.android.permissioncontroller.DeviceUtils; import com.android.permissioncontroller.R; +import com.android.permissioncontroller.ecm.EnhancedConfirmationStatsLogUtils; import com.android.permissioncontroller.permission.ui.auto.GrantPermissionsAutoViewHandler; import com.android.permissioncontroller.permission.ui.model.DenyButton; import com.android.permissioncontroller.permission.ui.model.GrantPermissionsViewModel; @@ -81,9 +93,9 @@ import com.android.permissioncontroller.permission.ui.model.Prompt; import com.android.permissioncontroller.permission.ui.wear.GrantPermissionsWearViewHandler; import com.android.permissioncontroller.permission.utils.ContextCompat; import com.android.permissioncontroller.permission.utils.KotlinUtils; -import com.android.permissioncontroller.permission.utils.MultiDeviceUtils; import com.android.permissioncontroller.permission.utils.PermissionMapping; import com.android.permissioncontroller.permission.utils.Utils; +import com.android.permissioncontroller.permission.utils.v35.MultiDeviceUtils; import java.util.ArrayList; import java.util.Arrays; @@ -104,6 +116,13 @@ public class GrantPermissionsActivity extends SettingsActivity private static final String KEY_SESSION_ID = GrantPermissionsActivity.class.getName() + "_REQUEST_ID"; + public static final String KEY_RESTRICTED_REQUESTED_PERMISSIONS = + GrantPermissionsActivity.class.getName() + "_RESTRICTED_REQUESTED_PERMISSIONS"; + public static final String KEY_UNRESTRICTED_REQUESTED_PERMISSIONS = + GrantPermissionsActivity.class.getName() + "_UNRESTRICTED_REQUESTED_PERMISSIONS"; + public static final String KEY_ORIGINAL_REQUESTED_PERMISSIONS = + GrantPermissionsActivity.class.getName() + "_ORIGINAL_REQUESTED_PERMISSIONS"; + public static final String ANNOTATION_ID = "link"; public static final int NEXT_BUTTON = 15; @@ -158,6 +177,17 @@ public class GrantPermissionsActivity extends SettingsActivity /** The current list of permissions requested, across all current requests for this app */ private List<String> mRequestedPermissions = new ArrayList<>(); + /** + * If any requested permissions are considered restricted by ECM, they will be stored here. + */ + private ArrayList<String> mRestrictedRequestedPermissionGroups = null; + + /** + * If any requested permissions are considered restricted by ECM, the non-restricted + * permissions will be stored here. + */ + private List<String> mUnrestrictedRequestedPermissions = null; + /** A list of permissions requested on an app's behalf by the system. Usually Implicitly * requested, although this isn't necessarily always the case. */ @@ -199,6 +229,16 @@ public class GrantPermissionsActivity extends SettingsActivity /** Which device the permission will affect. Default is the primary device. */ private int mTargetDeviceId = ContextCompat.DEVICE_ID_DEFAULT; + private ActivityResultLauncher<Intent> mShowWarningDialog = + registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + int resultCode = result.getResultCode(); + if (resultCode == RESULT_OK) { + finishAfterTransition(); + } + }); + @Override public void onCreate(Bundle icicle) { if (DeviceUtils.isAuto(this)) { @@ -218,7 +258,6 @@ public class GrantPermissionsActivity extends SettingsActivity getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM); } - int permissionsSdkLevel; if (PackageManager.ACTION_REQUEST_PERMISSIONS_FOR_OTHER.equals(getIntent().getAction())) { mIsSystemTriggered = true; mTargetPackage = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME); @@ -228,9 +267,6 @@ public class GrantPermissionsActivity extends SettingsActivity finishAfterTransition(); return; } - // We don't want to do any filtering in this case. - // These calls are coming from the system on behalf of the app. - permissionsSdkLevel = Build.VERSION_CODES.CUR_DEVELOPMENT; } else { // Cache this as this can only read on onCreate, not later. mTargetPackage = getCallingPackage(); @@ -242,7 +278,6 @@ public class GrantPermissionsActivity extends SettingsActivity } try { PackageInfo packageInfo = getPackageManager().getPackageInfo(mTargetPackage, 0); - permissionsSdkLevel = packageInfo.applicationInfo.targetSdkVersion; } catch (PackageManager.NameNotFoundException e) { Log.e(LOG_TAG, "Unable to get package info for the calling package.", e); finishAfterTransition(); @@ -258,8 +293,49 @@ public class GrantPermissionsActivity extends SettingsActivity } mRequestedPermissions = removeNullOrEmptyPermissions(requestedPermissionsArray); - if (mIsSystemTriggered) { - mSystemRequestedPermissions.addAll(mRequestedPermissions); + mOriginalRequestedPermissions = mRequestedPermissions.toArray(new String[0]); + + // Do validation if permissions are requested for a remote device or the dialog is being + // streamed to a remote device. + if (isDeviceAwarePermissionSupported(getApplicationContext())) { + mTargetDeviceId = getIntent().getIntExtra( + PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, + ContextCompat.DEVICE_ID_DEFAULT); + + // When the dialog is streamed to a remote device, verify requested permissions are all + // device aware and target device is the same as the remote device. Otherwise show a + // warning dialog. + if (getDeviceId() != ContextCompat.DEVICE_ID_DEFAULT) { + boolean showWarningDialog = mTargetDeviceId != getDeviceId(); + + for (String permission : mRequestedPermissions) { + if (!MultiDeviceUtils.isPermissionDeviceAware( + getApplicationContext(), mTargetDeviceId, permission)) { + showWarningDialog = true; + } + } + + if (showWarningDialog) { + mShowWarningDialog.launch( + new Intent(this, PermissionDialogStreamingBlockedActivity.class)); + return; + } + } else if (mTargetDeviceId != ContextCompat.DEVICE_ID_DEFAULT) { + // On the default device, when requested permissions are for a remote device, + // filter out non-device aware permissions. + for (int i = mRequestedPermissions.size() - 1; i >= 0; i--) { + if (!MultiDeviceUtils.isPermissionDeviceAware( + getApplicationContext(), + mTargetDeviceId, + mRequestedPermissions.get(i))) { + Log.e( + LOG_TAG, + "non-device aware permission is requested for a remote device: " + + mRequestedPermissions.get(i)); + mRequestedPermissions.remove(i); + } + } + } } if (mRequestedPermissions.isEmpty()) { @@ -267,36 +343,14 @@ public class GrantPermissionsActivity extends SettingsActivity return; } - if (MultiDeviceUtils.isDeviceAwareGrantFlowEnabled()) { - mTargetDeviceId = - getIntent() - .getIntExtra( - PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, - ContextCompat.DEVICE_ID_DEFAULT); + if (mIsSystemTriggered) { + mSystemRequestedPermissions.addAll(mRequestedPermissions); } - // If the permissions requested are for a remote device, check if each permission is device - // aware. - if (mTargetDeviceId != ContextCompat.DEVICE_ID_DEFAULT) { - if (!MultiDeviceUtils.isDeviceAwareGrantFlowEnabled()) { - Log.e(LOG_TAG, "targetDeviceId should be the default device if device aware grant" - + " flow is not enabled"); - finishAfterTransition(); - return; - } - - for (String permission : mRequestedPermissions) { - if (!MultiDeviceUtils.isPermissionDeviceAware(permission)) { - Log.e(LOG_TAG, "When target device is external, permission " + permission - + " needs to be device aware."); - finishAfterTransition(); - return; - } - } + if (blockRestrictedPermissions(icicle)) { + return; } - mOriginalRequestedPermissions = mRequestedPermissions.toArray(new String[0]); - synchronized (sCurrentGrantRequests) { mKey = new Pair<>(mTargetPackage, getTaskId()); if (!sCurrentGrantRequests.containsKey(mKey)) { @@ -390,6 +444,119 @@ public class GrantPermissionsActivity extends SettingsActivity } } + /* + * Block permissions that are restricted by ECM (Enhanced Confirmation Mode). + * + * If any requested permissions are restricted, then: + * + * - Strip them from mRequestedPermissions (so no grant dialog appears for those permissions). + * - Group the restricted permissions into permission groups. + * - Show the EnhancedConfirmationDialogActivity for each group. Each showing requires a + * cross-activity loop during which GrantPermissionActivity will be recreated. + * - Finally, continue processing all non-restricted requested permissions normally + * + * Returns true if we're going to show the ECM dialog (and therefore GrantPermissionsActivity + * will be recreated) + */ + @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM, codename = "VanillaIceCream") + private boolean blockRestrictedPermissions(Bundle icicle) { + if (!SdkLevel.isAtLeastV() || !Flags.enhancedConfirmationModeApisEnabled()) { + return false; + } + Context userContext = Utils.getUserContext(this, Process.myUserHandle()); + EnhancedConfirmationManager ecm = Utils.getSystemServiceSafe(userContext, + EnhancedConfirmationManager.class); + + // Retrieve ECM-related persisted permission lists + if (icicle != null) { + mOriginalRequestedPermissions = icicle.getStringArray( + KEY_ORIGINAL_REQUESTED_PERMISSIONS); + mRestrictedRequestedPermissionGroups = icicle.getStringArrayList( + KEY_RESTRICTED_REQUESTED_PERMISSIONS); + mUnrestrictedRequestedPermissions = icicle.getStringArrayList( + KEY_UNRESTRICTED_REQUESTED_PERMISSIONS); + } + // If these lists aren't persisted yet, it means we haven't yet divided + // mRequestedPermissions into restricted-vs-unrestricted, so do so. + if (mRestrictedRequestedPermissionGroups == null) { + ArraySet<String> restrictedPermGroups = new ArraySet<>(); + ArrayList<String> unrestrictedPermissions = new ArrayList<>(); + + for (String requestedPermission : mRequestedPermissions) { + String requestedPermGroup = PermissionMapping.getGroupOfPlatformPermission( + requestedPermission); + if (restrictedPermGroups.contains(requestedPermGroup)) { + continue; + } + if (requestedPermGroup != null && isPermissionEcmRestricted(ecm, + requestedPermission, mTargetPackage)) { + restrictedPermGroups.add(requestedPermGroup); + } else { + unrestrictedPermissions.add(requestedPermission); + } + } + mUnrestrictedRequestedPermissions = unrestrictedPermissions; + // If there are restricted permissions, and the ECM dialog has already been shown + // for this app, then we don't want to show it again. Act as if these restricted + // permissions weren't // requested at all, and log that we ignored them. + if (!restrictedPermGroups.isEmpty() && wasEcmDialogAlreadyShown(ecm, mTargetPackage)) { + for (String ignoredPermGroup : restrictedPermGroups) { + EnhancedConfirmationStatsLogUtils.INSTANCE.logDialogResultReported( + getPackageUid(getCallingPackage(), Process.myUserHandle()), + /* settingIdentifier */ ignoredPermGroup, /* firstShowForApp */ false, + EnhancedConfirmationStatsLogUtils.DialogResult.Suppressed); + } + mRestrictedRequestedPermissionGroups = new ArrayList<>(); + } else { + mRestrictedRequestedPermissionGroups = new ArrayList<>(restrictedPermGroups); + } + } + // If there are remaining restricted permission groups to process, show the ECM dialog + // for the next one, then recreate this activity. + if (!mRestrictedRequestedPermissionGroups.isEmpty()) { + String nextRestrictedPermissionGroup = mRestrictedRequestedPermissionGroups.remove(0); + try { + Intent intent = ecm.createRestrictedSettingDialogIntent(mTargetPackage, + nextRestrictedPermissionGroup); + intent.putExtra(EXTRA_IS_ECM_IN_APP, true); + startActivityForResult(intent, ECM_REQUEST_CODE); + return true; + } catch (PackageManager.NameNotFoundException e) { + mRequestedPermissions = mUnrestrictedRequestedPermissions; + } + } else { + mRequestedPermissions = mUnrestrictedRequestedPermissions; + } + return false; + } + + @SuppressLint("MissingPermission") + private int getPackageUid(String packageName, UserHandle user) { + try { + return getPackageManager().getApplicationInfoAsUser(packageName, 0, user).uid; + } catch (PackageManager.NameNotFoundException e) { + return android.os.Process.INVALID_UID; + } + } + + private boolean isPermissionEcmRestricted(EnhancedConfirmationManager ecm, + String requestedPermission, String packageName) { + try { + return ecm.isRestricted(packageName, requestedPermission); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + + private boolean wasEcmDialogAlreadyShown(EnhancedConfirmationManager ecm, + String packageName) { + try { + return ecm.isClearRestrictionAllowed(packageName); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + /** * A new GrantPermissionsActivity has opened for this same package. Merge its requested * permissions with the original ones set in the intent, and recalculate the grant states. @@ -685,30 +852,45 @@ public class GrantPermissionsActivity extends SettingsActivity return buttonArray; } - // LINT.IfChange(dispatchTouchEvent) @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - View rootView = getWindow().getDecorView(); - if (rootView.getTop() != 0) { - // We are animating the top view, need to compensate for that in motion events. - ev.setLocation(ev.getX(), ev.getY() - rootView.getTop()); - } - final int x = (int) ev.getX(); - final int y = (int) ev.getY(); - if ((x < 0) || (y < 0) || (x > (rootView.getWidth())) || (y > (rootView.getHeight()))) { - if (MotionEvent.ACTION_DOWN == ev.getAction()) { - mViewHandler.onCancelled(); - } + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_ESCAPE + && event.getRepeatCount() == 0 + && event.hasNoModifiers()) { + event.startTracking(); + mViewHandler.onCancelled(); finishAfterTransition(); + return true; } - return super.dispatchTouchEvent(ev); + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_ESCAPE + && event.isTracking() + && !event.isCanceled()) { + // Mark it as handled since we did handle the down event + return true; + } + return super.onKeyUp(keyCode, event); } - // LINT.ThenChange(PermissionRationaleActivity.java:dispatchTouchEvent) @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); + if (SdkLevel.isAtLeastV() && Flags.enhancedConfirmationModeApisEnabled()) { + outState.putStringArrayList(KEY_RESTRICTED_REQUESTED_PERMISSIONS, + mRestrictedRequestedPermissionGroups != null ? new ArrayList<>( + mRestrictedRequestedPermissionGroups) : null); + outState.putStringArrayList(KEY_UNRESTRICTED_REQUESTED_PERMISSIONS, + mUnrestrictedRequestedPermissions != null ? new ArrayList<>( + mUnrestrictedRequestedPermissions) : null); + outState.putStringArray(KEY_ORIGINAL_REQUESTED_PERMISSIONS, + mOriginalRequestedPermissions); + } + if (mViewHandler == null || mViewModel == null) { return; } @@ -734,6 +916,12 @@ public class GrantPermissionsActivity extends SettingsActivity @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); + if (SdkLevel.isAtLeastV() && Flags.enhancedConfirmationModeApisEnabled()) { + if (requestCode == ECM_REQUEST_CODE) { + recreate(); + return; + } + } if (requestCode != APP_PERMISSION_REQUEST_CODE && requestCode != PHOTO_PICKER_REQUEST_CODE) { return; diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java index 4cd595b55..df5b98ae7 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java @@ -156,6 +156,9 @@ public final class ManagePermissionsActivity extends SettingsActivity { } super.onCreate(savedInstanceState); + // TODO(b/309578419): Make this activity handle insets properly and then remove this. + getTheme().applyStyle(R.style.OptOutEdgeToEdgeEnforcement, /* force */ false); + // If this is not a phone or a watch (which uses the Navigation component), and there // is a previous instance, re-use its Fragment instead of making a new one. if ((DeviceUtils.isTelevision(this) || DeviceUtils.isAuto(this)) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/PermissionDialogStreamingBlockedActivity.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/PermissionDialogStreamingBlockedActivity.kt new file mode 100644 index 000000000..29f9ed2c7 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/PermissionDialogStreamingBlockedActivity.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui + +import android.app.AlertDialog +import android.os.Bundle +import androidx.fragment.app.FragmentActivity +import com.android.permissioncontroller.R + +/** + * In some scenarios we want to prevent the permission grant dialog from streaming to a remote + * device. If the streaming is blocked show a warning dialog rendered by this activity. + */ +class PermissionDialogStreamingBlockedActivity : FragmentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + AlertDialog.Builder(this) + .setTitle(R.string.permission_grant_dialog_streaming_blocked_title) + .setMessage(R.string.permission_grant_dialog_streaming_blocked_description) + .setPositiveButton(R.string.ongoing_usage_dialog_ok, null) + .setOnDismissListener() { + setResult(RESULT_OK) + finish() + } + .create() + .show() + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoReviewPermissionDecisionsFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoReviewPermissionDecisionsFragment.kt index 99f5c85e4..2350a5d71 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoReviewPermissionDecisionsFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoReviewPermissionDecisionsFragment.kt @@ -35,6 +35,7 @@ import com.android.permissioncontroller.PermissionControllerStatsLog.RECENT_PERM import com.android.permissioncontroller.PermissionControllerStatsLog.RECENT_PERMISSION_DECISIONS_INTERACTED__ACTION__VIEW_ALL_CLICKED import com.android.permissioncontroller.R import com.android.permissioncontroller.auto.AutoSettingsFrameFragment +import com.android.permissioncontroller.auto.DrivingDecisionReminderService import com.android.permissioncontroller.permission.data.v33.PermissionDecision import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity import com.android.permissioncontroller.permission.ui.model.v33.ReviewPermissionDecisionsViewModel @@ -98,6 +99,7 @@ class AutoReviewPermissionDecisionsFragment : AutoSettingsFrameFragment() { requireArguments().containsKey(EXTRA_SOURCE) && (requireArguments().getString(EXTRA_SOURCE) == EXTRA_SOURCE_NOTIFICATION) ) { + DrivingDecisionReminderService.cancelNotification(requireActivity()) logDecisionReminderNotificationClicked() } val factory = diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java index 7fa51dd8a..32f0c677c 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java @@ -58,6 +58,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RadioButton; import android.widget.Switch; @@ -83,6 +84,7 @@ import com.android.permissioncontroller.permission.ui.model.AppPermissionViewMod import com.android.permissioncontroller.permission.ui.v33.AdvancedConfirmDialogArgs; import com.android.permissioncontroller.permission.utils.KotlinUtils; import com.android.permissioncontroller.permission.utils.Utils; +import com.android.permissioncontroller.permission.utils.v35.MultiDeviceUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.widget.ActionBarShadowController; @@ -106,10 +108,12 @@ public class AppPermissionFragment extends SettingsWithLargeHeader private static final long EDIT_PHOTOS_BUTTON_ANIMATION_LENGTH_MS = 200L; static final String GRANT_CATEGORY = "grant_category"; + static final String PERSISTENT_DEVICE_ID = "persistent_device_id"; private @NonNull AppPermissionViewModel mViewModel; private @NonNull ViewGroup mAppPermissionRationaleContainer; private @NonNull ViewGroup mAppPermissionRationaleContent; + private @NonNull FrameLayout mAllowButtonFrame; private @NonNull RadioButton mAllowButton; private @NonNull RadioButton mAllowAlwaysButton; private @NonNull RadioButton mAllowForegroundButton; @@ -135,6 +139,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader // This prevents the user from clicking the photo picker button multiple times in succession private boolean mPhotoPickerTriggered; private long mSessionId; + private String mPersistentDeviceId; private @NonNull String mPackageLabel; private @NonNull String mPermGroupLabel; @@ -198,8 +203,12 @@ public class AppPermissionFragment extends SettingsWithLargeHeader mPackageName, mUser); mSessionId = getArguments().getLong(EXTRA_SESSION_ID, INVALID_SESSION_ID); + mPersistentDeviceId = getArguments().getString(PERSISTENT_DEVICE_ID, + MultiDeviceUtils.getDefaultDevicePersistentDeviceId()); + AppPermissionViewModelFactory factory = new AppPermissionViewModelFactory( - getActivity().getApplication(), mPackageName, mPermGroupName, mUser, mSessionId); + getActivity().getApplication(), mPackageName, mPermGroupName, mUser, mSessionId, + mPersistentDeviceId); mViewModel = new ViewModelProvider(this, factory).get(AppPermissionViewModel.class); Handler delayHandler = new Handler(Looper.getMainLooper()); mViewModel.getButtonStateLiveData().observe(this, buttonState -> { @@ -230,8 +239,15 @@ public class AppPermissionFragment extends SettingsWithLargeHeader setHeader(mPackageIcon, mPackageLabel, null, null, false); updateHeader(root.requireViewById(R.id.large_header)); - ((TextView) root.requireViewById(R.id.permission_message)).setText( - context.getString(R.string.app_permission_header, mPermGroupLabel)); + String text = null; + if (MultiDeviceUtils.isDefaultDeviceId(mPersistentDeviceId)) { + text = context.getString(R.string.app_permission_header, mPermGroupLabel); + } else { + final String deviceName = MultiDeviceUtils.getDeviceName(context, mPersistentDeviceId); + text = context.getString(R.string.app_permission_header_with_device_name, + mPermGroupLabel, deviceName); + } + ((TextView) root.requireViewById(R.id.permission_message)).setText(text); String caller = getArguments().getString(EXTRA_CALLER_NAME); @@ -258,6 +274,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader footerInfoText.setVisibility(View.GONE); } + mAllowButtonFrame = root.requireViewById(R.id.allow_radio_button_frame); mAllowButton = root.requireViewById(R.id.allow_radio_button); mAllowAlwaysButton = root.requireViewById(R.id.allow_always_radio_button); mAllowForegroundButton = root.requireViewById(R.id.allow_foreground_only_radio_button); @@ -389,12 +406,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader } else if (states == null) { return; } - - mAllowButton.setOnClickListener((v) -> { - mViewModel.requestChange(false, this, this, ChangeRequest.GRANT_FOREGROUND, - APP_PERMISSION_FRAGMENT_ACTION_REPORTED__BUTTON_PRESSED__ALLOW); - setResult(GRANTED_ALWAYS); - }); + mAllowButtonFrame.setOnClickListener((v) -> allowButtonFrameClickListener()); mAllowAlwaysButton.setOnClickListener((v) -> { if (mIsStorageGroup) { showConfirmDialog(ChangeRequest.GRANT_ALL_FILE_ACCESS, @@ -499,6 +511,17 @@ public class AppPermissionFragment extends SettingsWithLargeHeader } } + private void allowButtonFrameClickListener() { + if (!mAllowButton.isEnabled()) { + mViewModel.handleDisabledAllowButton(this); + } else { + mAllowButton.setChecked(true); + mViewModel.requestChange(false, this, this, ChangeRequest.GRANT_FOREGROUND, + APP_PERMISSION_FRAGMENT_ACTION_REPORTED__BUTTON_PRESSED__ALLOW); + setResult(GRANTED_ALWAYS); + } + } + private void setButtonState(CompoundButton button, AppPermissionViewModel.ButtonState state) { int visible = state.isShown() ? View.VISIBLE : View.GONE; button.setVisibility(visible); diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java index 4bc14ed24..eff5738fc 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java @@ -64,6 +64,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import com.android.modules.utils.build.SdkLevel; +import com.android.permission.flags.Flags; import com.android.permissioncontroller.PermissionControllerStatsLog; import com.android.permissioncontroller.R; import com.android.permissioncontroller.permission.model.livedatatypes.HibernationSettingState; @@ -76,6 +77,7 @@ import com.android.permissioncontroller.permission.ui.model.AppPermissionGroupsV import com.android.permissioncontroller.permission.utils.KotlinUtils; import com.android.permissioncontroller.permission.utils.StringUtils; import com.android.permissioncontroller.permission.utils.Utils; +import com.android.permissioncontroller.permission.utils.v35.MultiDeviceUtils; import com.android.settingslib.HelpUtils; import com.android.settingslib.widget.FooterPreference; @@ -349,7 +351,19 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i PermissionControlPreference preference = new PermissionControlPreference(context, mPackageName, groupName, mUser, AppPermissionGroupsFragment.class.getName(), sessionId, grantCategory.getCategoryName(), true); - preference.setTitle(KotlinUtils.INSTANCE.getPermGroupLabel(context, groupName)); + + CharSequence permissionGroupName = KotlinUtils.INSTANCE.getPermGroupLabel(context, + groupName); + if (MultiDeviceUtils.isDefaultDeviceId(groupInfo.getPersistentDeviceId())) { + preference.setTitle(permissionGroupName); + } else { + final String deviceName = MultiDeviceUtils.getDeviceName(context, + groupInfo.getPersistentDeviceId()); + preference.setTitle(context.getString( + R.string.permission_group_name_with_device_name, + permissionGroupName, deviceName)); + preference.setPersistentDeviceId(groupInfo.getPersistentDeviceId()); + } preference.setIcon(KotlinUtils.INSTANCE.getPermGroupIcon(context, groupName)); preference.setKey(groupName); String summary = mViewModel.getPreferenceSummary(groupInfo, context, @@ -431,8 +445,10 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i int switchTitleId; if (isHibernationEnabled()) { if (SdkLevel.isAtLeastT()) { - switchTitleId = R.string.unused_apps_label_v2; - autoRevokeSwitch.setSummary(R.string.unused_apps_summary); + switchTitleId = isArchivingEnabled() ? R.string.unused_apps_label_v3 + : R.string.unused_apps_label_v2; + autoRevokeSwitch.setSummary(isArchivingEnabled() ? R.string.unused_apps_summary_v2 + : R.string.unused_apps_summary); } else { switchTitleId = R.string.unused_apps_label; } @@ -456,6 +472,10 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i autoRevokeCategory.addPreference(autoRevokeSummary); } + private boolean isArchivingEnabled() { + return SdkLevel.isAtLeastV() && Flags.archivingReadOnly(); + } + private void setAutoRevokeToggleState(HibernationSettingState state) { if (state == null || !mViewModel.getPackagePermGroupsLiveData().isInitialized() || getPreferenceScreen() == null || getListView() == null || getView() == null) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java index 20dc50130..76e52ad94 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionAppsFragment.java @@ -34,6 +34,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; +import android.os.UserManager; import android.provider.Settings; import android.safetycenter.SafetyCenterManager; import android.util.ArrayMap; @@ -115,6 +116,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem private PermissionUsages mPermissionUsages; private List<AppPermissionUsage> mAppPermissionUsages = new ArrayList<>(); private Boolean mSensorStatus; + private UserManager mUserManager; @Override public void onCreate(Bundle savedInstanceState) { @@ -168,6 +170,8 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem mViewModel.getSensorStatusLiveData().observe(this, this::setSensorStatus); } } + + mUserManager = Utils.getSystemServiceSafe(getContext(), UserManager.class); } @Override @@ -436,6 +440,9 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem } for (Pair<String, UserHandle> packageUserLabel : packages) { + if (!Utils.shouldShowInSettings(packageUserLabel.getSecond(), mUserManager)) { + continue; + } String packageName = packageUserLabel.getFirst(); UserHandle user = packageUserLabel.getSecond(); diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionControlPreference.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionControlPreference.java index 3d47909e8..039aca39d 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionControlPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/PermissionControlPreference.java @@ -21,6 +21,7 @@ import static android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP; import static com.android.permissioncontroller.Constants.EXTRA_SESSION_ID; import static com.android.permissioncontroller.permission.ui.ManagePermissionsActivity.EXTRA_CALLER_NAME; import static com.android.permissioncontroller.permission.ui.handheld.AppPermissionFragment.GRANT_CATEGORY; +import static com.android.permissioncontroller.permission.ui.handheld.AppPermissionFragment.PERSISTENT_DEVICE_ID; import static com.android.permissioncontroller.permission.utils.KotlinUtilsKt.navigateSafe; import android.Manifest; @@ -69,6 +70,7 @@ public class PermissionControlPreference extends Preference { private @NonNull long mSessionId; private boolean mHasNavGraph; private @NonNull UserHandle mUser; + private @Nullable String mPersistentDeviceId; public PermissionControlPreference(@NonNull Context context, @NonNull AppPermissionGroup group, @NonNull String caller) { @@ -237,6 +239,7 @@ public class PermissionControlPreference extends Preference { args.putString(EXTRA_CALLER_NAME, mCaller); args.putLong(EXTRA_SESSION_ID, mSessionId); args.putString(GRANT_CATEGORY, mGranted); + args.putString(PERSISTENT_DEVICE_ID, mPersistentDeviceId); navigateSafe(Navigation.findNavController(holder.itemView), R.id.perm_groups_to_app, args); } else { @@ -254,6 +257,10 @@ public class PermissionControlPreference extends Preference { }); } + public void setPersistentDeviceId(String persistentDeviceId) { + this.mPersistentDeviceId = persistentDeviceId; + } + private void setIcons(PreferenceViewHolder holder, @Nullable List<Integer> icons, int frameId) { ViewGroup frame = (ViewGroup) holder.findViewById(frameId); if (icons != null && !icons.isEmpty()) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/CompositeCircleView.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/CompositeCircleView.java index 64346c4aa..5965cfcf5 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/CompositeCircleView.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/CompositeCircleView.java @@ -19,10 +19,13 @@ package com.android.permissioncontroller.permission.ui.handheld.v31; import android.content.Context; import android.util.AttributeSet; import android.widget.FrameLayout; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.permissioncontroller.R; + /** * Configured to draw a set of contiguous partial circles via {@link PartialCircleView}, which * are generated from the relative weight of values and corresponding colors given to @@ -73,8 +76,10 @@ public class CompositeCircleView extends FrameLayout { * @param values relative weights, used to size the partial circles * @param colors colors corresponding to relative weights * @param strokeWidth stroke width to apply to all contained partial circles + * @param labels the permission labels to set the ContentDescription with % value */ - public void configure(float startAngle, int[] values, int[] colors, int strokeWidth) { + public void configure(float startAngle, int[] values, int[] colors, int strokeWidth, + TextView[] labels) { removeAllViews(); mValues = values; @@ -121,6 +126,13 @@ public class CompositeCircleView extends FrameLayout { float sweepAngle = (values[i] / total) * allocatedDegrees; pcv.setSweepAngle(sweepAngle); + if (labels[i] != null) { + int percentage = Math.round((values[i] / total) * 100); + String contextDescription = getContext().getString( + R.string.privdash_usage_percent, labels[i].getText(), percentage); + labels[i].setContentDescription(contextDescription); + } + mPartialCircleCenterAngles[i] = (startAngle + (sweepAngle * 0.5f)) % 360; if (i > 0) { float angleDiff = diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageFragment.java index e28387f5b..6c2e6c494 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageFragment.java @@ -28,6 +28,8 @@ import android.app.ActionBar; import android.content.Context; import android.os.Build; import android.os.Bundle; +import android.os.SystemClock; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -42,7 +44,9 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.permissioncontroller.R; import com.android.permissioncontroller.permission.ui.handheld.SettingsWithLargeHeader; -import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageViewModel; +import com.android.permissioncontroller.permission.ui.viewmodel.BasePermissionUsageViewModel; +import com.android.permissioncontroller.permission.ui.viewmodel.PermissionUsageViewModelFactory; +import com.android.permissioncontroller.permission.ui.viewmodel.PermissionUsagesUiState; import com.android.permissioncontroller.permission.utils.KotlinUtils; import com.android.settingslib.HelpUtils; @@ -54,7 +58,7 @@ import java.util.Map; /** The main page for the privacy dashboard. */ @RequiresApi(Build.VERSION_CODES.S) public class PermissionUsageFragment extends SettingsWithLargeHeader { - + private static final String LOG_TAG = PermissionUsageFragment.class.getSimpleName(); private static final Map<String, Integer> PERMISSION_GROUP_ORDER = Map.of( Manifest.permission_group.LOCATION, 0, @@ -62,6 +66,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { Manifest.permission_group.MICROPHONE, 2); private static final int DEFAULT_ORDER = 3; + public static final boolean DEBUG = true; + // Pie chart in this screen will be the first child. // Hence we use PERMISSION_GROUP_ORDER + 1 here. private static final int PERMISSION_USAGE_INITIAL_EXPANDED_CHILDREN_COUNT = @@ -76,7 +82,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { private static final int MENU_SHOW_7_DAYS_DATA = Menu.FIRST + 4; private static final int MENU_SHOW_24_HOURS_DATA = Menu.FIRST + 5; - private PermissionUsageViewModel mViewModel; + private BasePermissionUsageViewModel mViewModel; private boolean mHasSystemApps; private MenuItem mShowSystemMenu; @@ -89,21 +95,23 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { /** Unique Id of a request */ private long mSessionId; + // track total time for dashboard loading. + private long mStartTime; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + mStartTime = SystemClock.elapsedRealtime(); if (savedInstanceState != null) { mSessionId = savedInstanceState.getLong(SESSION_ID_KEY); } else { mSessionId = getArguments().getLong(EXTRA_SESSION_ID, INVALID_SESSION_ID); } - PermissionUsageViewModel.PermissionUsageViewModelFactory factory = - new PermissionUsageViewModel.PermissionUsageViewModelFactory( + PermissionUsageViewModelFactory factory = new PermissionUsageViewModelFactory( getActivity().getApplication(), this, new Bundle()); - mViewModel = new ViewModelProvider(this, factory).get(PermissionUsageViewModel.class); + mViewModel = new ViewModelProvider(this, factory) + .get(BasePermissionUsageViewModel.class); // Start out with 'other' permissions not expanded. mOtherExpanded = false; @@ -194,11 +202,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE, R.string.menu_show_system); mHideSystemMenu = menu.add(Menu.NONE, MENU_HIDE_SYSTEM, Menu.NONE, R.string.menu_hide_system); - boolean showSystem = - mViewModel.getShowSystemAppsLiveData().getValue() != null - ? mViewModel.getShowSystemAppsLiveData().getValue() - : false; - updateShowSystemToggle(showSystem); + updateShowSystemToggle(mViewModel.getShowSystemApps()); if (KotlinUtils.INSTANCE.is7DayToggleEnabled()) { mShow7DaysDataMenu = @@ -213,11 +217,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { MENU_SHOW_24_HOURS_DATA, Menu.NONE, R.string.menu_show_24_hours_data); - boolean show7Days = - mViewModel.getShow7DaysLiveData().getValue() != null - ? mViewModel.getShow7DaysLiveData().getValue() - : false; - updateShow7DaysToggle(show7Days); + updateShow7DaysToggle(mViewModel.getShow7DaysData()); } HelpUtils.prepareHelpMenuItem( @@ -236,16 +236,21 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { PERMISSION_USAGE_FRAGMENT_INTERACTION, mSessionId, PERMISSION_USAGE_FRAGMENT_INTERACTION__ACTION__SHOW_SYSTEM_CLICKED); - mViewModel.updateShowSystem(true); + mStartTime = SystemClock.elapsedRealtime(); + updateAllUI(mViewModel.updateShowSystem(true)); break; case MENU_HIDE_SYSTEM: - mViewModel.updateShowSystem(false); + mStartTime = SystemClock.elapsedRealtime(); + updateAllUI(mViewModel.updateShowSystem(false)); break; case MENU_SHOW_7_DAYS_DATA: - mViewModel.updateShow7Days(KotlinUtils.INSTANCE.is7DayToggleEnabled()); + mStartTime = SystemClock.elapsedRealtime(); + + updateAllUI(mViewModel.updateShow7Days(KotlinUtils.INSTANCE.is7DayToggleEnabled())); break; case MENU_SHOW_24_HOURS_DATA: - mViewModel.updateShow7Days(false); + mStartTime = SystemClock.elapsedRealtime(); + updateAllUI(mViewModel.updateShow7Days(false)); break; } return super.onOptionsItemSelected(item); @@ -293,8 +298,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { } /** Updates page content and menu items. */ - private void updateAllUI( - PermissionUsageViewModel.PermissionUsagesUiData permissionUsagesUiData) { + private void updateAllUI(PermissionUsagesUiState permissionUsagesUiData) { if (getActivity() == null) { return; } @@ -319,40 +323,27 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { mSessionId, PERMISSION_USAGE_FRAGMENT_INTERACTION__ACTION__SEE_OTHER_PERMISSIONS_CLICKED); }); - boolean containsSystemAppUsages = permissionUsagesUiData.getContainsSystemAppUsages(); + boolean containsSystemAppUsages = permissionUsagesUiData.getShouldShowSystemToggle(); Map<String, Integer> permissionGroupWithUsageCounts = - permissionUsagesUiData.getPermissionGroupsWithUsageCount(); + permissionUsagesUiData.getPermissionGroupUsageCount(); List<Map.Entry<String, Integer>> permissionGroupWithUsageCountsEntries = new ArrayList(permissionGroupWithUsageCounts.entrySet()); permissionGroupWithUsageCountsEntries.sort(Comparator.comparing( (Map.Entry<String, Integer> permissionGroupWithUsageCount) -> PERMISSION_GROUP_ORDER.getOrDefault( - permissionGroupWithUsageCount.getKey(), - DEFAULT_ORDER)) - .thenComparing( - (Map.Entry<String, Integer> permissionGroupWithUsageCount) -> - KotlinUtils.INSTANCE - .getPermGroupLabel( - context, - permissionGroupWithUsageCount - .getKey()) - .toString())); + permissionGroupWithUsageCount.getKey(), DEFAULT_ORDER)) + .thenComparing((Map.Entry<String, Integer> permissionGroupWithUsageCount) -> + mViewModel.getPermissionGroupLabel( + context, permissionGroupWithUsageCount.getKey()))); if (mHasSystemApps != containsSystemAppUsages) { mHasSystemApps = containsSystemAppUsages; } - boolean show7Days = - mViewModel.getShow7DaysLiveData().getValue() != null - ? mViewModel.getShow7DaysLiveData().getValue() - : false; + boolean show7Days = mViewModel.getShow7DaysData(); updateShow7DaysToggle(show7Days); - boolean showSystem = - mViewModel.getShowSystemAppsLiveData().getValue() != null - ? mViewModel.getShowSystemAppsLiveData().getValue() - : false; - updateShowSystemToggle(showSystem); + updateShowSystemToggle(mViewModel.getShowSystemApps()); mGraphic = new PermissionUsageGraphicPreference(context, show7Days); screen.addPreference(mGraphic); @@ -366,6 +357,11 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { screen.setSummary(advancedInfoSummary); addUIContent(context, permissionGroupWithUsageCountsEntries, category); + long totalTimeTaken = SystemClock.elapsedRealtime() - mStartTime; + if (DEBUG) { + Log.i(LOG_TAG, "Total time taken in dashboard loading = " + totalTimeTaken + " ms"); + } + Log.v(LOG_TAG, "Privacy dashboard data = " + permissionUsagesUiData); } private CharSequence getAdvancedInfoSummaryString( @@ -381,7 +377,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { permissionGroupWithUsageCounts .get(PERMISSION_USAGE_INITIAL_EXPANDED_CHILDREN_COUNT - 1) .getKey(); - return KotlinUtils.INSTANCE.getPermGroupLabel(context, permGroupName); + return mViewModel.getPermissionGroupLabel(context, permGroupName); } String permGroupName1 = @@ -392,10 +388,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { permissionGroupWithUsageCounts .get(PERMISSION_USAGE_INITIAL_EXPANDED_CHILDREN_COUNT) .getKey(); - CharSequence permGroupLabel1 = - KotlinUtils.INSTANCE.getPermGroupLabel(context, permGroupName1); - CharSequence permGroupLabel2 = - KotlinUtils.INSTANCE.getPermGroupLabel(context, permGroupName2); + CharSequence permGroupLabel1 = mViewModel.getPermissionGroupLabel(context, permGroupName1); + CharSequence permGroupLabel2 = mViewModel.getPermissionGroupLabel(context, permGroupName2); // case for 2 extra items in the advanced info if (size == PERMISSION_USAGE_INITIAL_EXPANDED_CHILDREN_COUNT + 1) { @@ -421,14 +415,9 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader { Context context, List<Map.Entry<String, Integer>> permissionGroupWithUsageCounts, PreferenceCategory category) { - boolean showSystem = - mViewModel.getShowSystemAppsLiveData().getValue() != null - ? mViewModel.getShowSystemAppsLiveData().getValue() - : false; - boolean show7Days = - mViewModel.getShow7DaysLiveData().getValue() != null - ? mViewModel.getShow7DaysLiveData().getValue() - : false; + boolean showSystem = mViewModel.getShowSystemApps(); + boolean show7Days = mViewModel.getShow7DaysData(); + for (int i = 0; i < permissionGroupWithUsageCounts.size(); i++) { Map.Entry<String, Integer> permissionGroupWithUsageCount = permissionGroupWithUsageCounts.get(i); diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageGraphicPreference.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageGraphicPreference.java index d0a98d9e9..39bb4ed2b 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageGraphicPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/v31/PermissionUsageGraphicPreference.java @@ -197,7 +197,7 @@ public class PermissionUsageGraphicPreference extends Preference { // Configure circle and labeler. ccvl.configure(R.id.composite_circle_view, centerLabel, labels, labelRadiusScalar); // Start at angle 300 (top right) to allow for small segments for cam, mic, and loc. - ccv.configure(300, counts, colors, circleStrokeWidth); + ccv.configure(300, counts, colors, circleStrokeWidth, labels); } private int getUsageCount(String group) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/legacy/PermissionUsageDetailsViewModelLegacy.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/legacy/PermissionUsageDetailsViewModelLegacy.kt index 14aff67ba..c782a85f8 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/legacy/PermissionUsageDetailsViewModelLegacy.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/legacy/PermissionUsageDetailsViewModelLegacy.kt @@ -183,9 +183,9 @@ class PermissionUsageDetailsViewModelLegacy( private fun extractAppPermissionTimelineUsagesForGroup( appPermissionUsages: List<AppPermissionUsage>, group: String - ): List<AppPermissionTimelineUsage> = - appPermissionUsages - .filter { !Utils.getExemptedPackages(roleManager).contains(it.packageName) } + ): List<AppPermissionTimelineUsage> { + val exemptedPackages = Utils.getExemptedPackages(roleManager) + return appPermissionUsages.filter { !exemptedPackages.contains(it.packageName) } .map { appPermissionUsage -> getAppPermissionTimelineUsages( appPermissionUsage.app, @@ -193,6 +193,7 @@ class PermissionUsageDetailsViewModelLegacy( ) } .flatten() + } /** Returns whether the show/hide system toggle should be displayed in the UI. */ private fun shouldDisplayShowSystemToggle( diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/legacy/PermissionUsageViewModel.kt index fa5b1b685..eec160fc9 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/legacy/PermissionUsageViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,17 +14,19 @@ * limitations under the License. */ -package com.android.permissioncontroller.permission.ui.model.v31 +package com.android.permissioncontroller.permission.ui.legacy import android.Manifest import android.app.Application import android.app.role.RoleManager +import android.content.Context import android.os.Build import android.os.Bundle import android.os.UserHandle +import android.os.UserManager import androidx.annotation.RequiresApi import androidx.lifecycle.AbstractSavedStateViewModelFactory -import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.savedstate.SavedStateRegistryOwner @@ -36,8 +38,11 @@ import com.android.permissioncontroller.permission.data.get import com.android.permissioncontroller.permission.data.v31.AllLightPackageOpsLiveData import com.android.permissioncontroller.permission.model.livedatatypes.v31.AppPermissionId import com.android.permissioncontroller.permission.model.livedatatypes.v31.LightPackageOps +import com.android.permissioncontroller.permission.ui.legacy.PermissionUsageViewModel.Companion.SHOULD_SHOW_7_DAYS_KEY import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageDetailsViewModel.Companion.SHOULD_SHOW_SYSTEM_KEY -import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageViewModel.Companion.SHOULD_SHOW_7_DAYS_KEY +import com.android.permissioncontroller.permission.ui.viewmodel.BasePermissionUsageViewModel +import com.android.permissioncontroller.permission.ui.viewmodel.PermissionUsageViewModelV2 +import com.android.permissioncontroller.permission.ui.viewmodel.PermissionUsagesUiState import com.android.permissioncontroller.permission.utils.KotlinUtils import com.android.permissioncontroller.permission.utils.PermissionMapping import com.android.permissioncontroller.permission.utils.Utils @@ -46,19 +51,22 @@ import java.util.concurrent.TimeUnit import kotlin.math.max /** - * [ViewModel] for handheld Permissions Usage UI. + * Legacy [ViewModel] for handheld Permissions Usage UI. * - * Note that this class replaces [PermissionUsageViewModelLegacy] to rely on [LiveData] instead of - * [PermissionUsages] loader. + * Note that this class is replaced by [PermissionUsageViewModelV2]. */ class PermissionUsageViewModel( private val state: SavedStateHandle, app: Application, -) : AndroidViewModel(app) { +) : BasePermissionUsageViewModel(app) { + private val userManager = + Utils.getSystemServiceSafe(app.applicationContext, UserManager::class.java) private val roleManager = Utils.getSystemServiceSafe(app.applicationContext, RoleManager::class.java) private val exemptedPackages: Set<String> = Utils.getExemptedPackages(roleManager) + @SuppressWarnings("NewApi") + // TODO : b/330215842 - Cleanup NewApi suppression's private val mAllLightPackageOpsLiveData = AllLightPackageOpsLiveData(app) private val appPermGroupUiInfoLiveDataList = mutableMapOf<AppPermissionId, AppPermGroupUiInfoLiveData>() @@ -66,40 +74,59 @@ class PermissionUsageViewModel( mutableMapOf<Pair<String, UserHandle>, LightPackageInfoLiveData>() private val standardPermGroupNamesLiveData = StandardPermGroupNamesLiveData - val showSystemAppsLiveData = state.getLiveData(SHOULD_SHOW_SYSTEM_KEY, false) - val show7DaysLiveData = state.getLiveData(SHOULD_SHOW_7_DAYS_KEY, false) + private var showSystemApps = false + private var show7DaysData = false + + override fun getPermissionUsagesUiLiveData(): LiveData<PermissionUsagesUiState> { + return permissionUsagesUiLiveData + } + + override fun getShowSystemApps(): Boolean { + return showSystemApps + } + + override fun getShow7DaysData(): Boolean { + return show7DaysData + } /** Updates whether system app permissions usage should be displayed in the UI. */ - fun updateShowSystem(showSystem: Boolean) { - if (showSystem != state[SHOULD_SHOW_SYSTEM_KEY]) { - state[SHOULD_SHOW_SYSTEM_KEY] = showSystem - } + override fun updateShowSystem(showSystem: Boolean): PermissionUsagesUiState { + showSystemApps = showSystem + return buildPermissionUsagesUiData() } /** Updates whether 7 days usage or 1 day usage should be displayed in the UI. */ - fun updateShow7Days(show7Days: Boolean) { - if (show7Days != state[SHOULD_SHOW_7_DAYS_KEY]) { - state[SHOULD_SHOW_7_DAYS_KEY] = show7Days - } + override fun updateShow7Days(show7Days: Boolean): PermissionUsagesUiState { + show7DaysData = show7Days + return buildPermissionUsagesUiData() } /** Builds a [PermissionUsagesUiData] containing all the data necessary to render the UI. */ - private fun buildPermissionUsagesUiData(): PermissionUsagesUiData { + private fun buildPermissionUsagesUiData(): PermissionUsagesUiState { val curTime = System.currentTimeMillis() - val showSystem: Boolean = state[SHOULD_SHOW_SYSTEM_KEY] ?: false - val show7Days: Boolean = state[SHOULD_SHOW_7_DAYS_KEY] ?: false + val showPermissionUsagesDuration = - if (KotlinUtils.is7DayToggleEnabled() && show7Days) { + if (KotlinUtils.is7DayToggleEnabled() && show7DaysData) { TIME_7_DAYS_DURATION } else { TIME_24_HOURS_DURATION } val startTime = max(curTime - showPermissionUsagesDuration, Instant.EPOCH.toEpochMilli()) - return PermissionUsagesUiData( - showSystem, - show7Days, + return PermissionUsagesUiState( mAllLightPackageOpsLiveData.containsSystemAppUsages(startTime), - mAllLightPackageOpsLiveData.buildPermissionGroupsWithUsageCounts(startTime, showSystem) + mAllLightPackageOpsLiveData.buildPermissionGroupsWithUsageCounts( + startTime, + showSystemApps + ) + ) + } + + private val permissionGroupLabels = mutableMapOf<String, String>() + + override fun getPermissionGroupLabel(context: Context, permissionGroup: String): String { + return permissionGroupLabels.getOrDefault( + permissionGroup, + KotlinUtils.getPermGroupLabel(context, permissionGroup).toString() ) } @@ -114,7 +141,10 @@ class PermissionUsageViewModel( } val eligibleLightPackageOpsList: List<LightPackageOps> = - getAllLightPackageOps()?.filterOutExemptedApps() ?: listOf() + getAllLightPackageOps()?.filterOutExemptedApps()?.filter { + Utils.shouldShowInSettings(it.userHandle, userManager) + } + ?: listOf() for (lightPackageOps: LightPackageOps in eligibleLightPackageOpsList) { val permGroupsToLastAccess: List<Map.Entry<String, Long>> = @@ -219,6 +249,8 @@ class PermissionUsageViewModel( } /** Filters out app permissions when the permission has not been requested by the app. */ + @SuppressWarnings("NewApi") + // TODO : b/330215842 - Cleanup NewApi suppression's private fun Collection<Map.Entry<String, Long>>.filterOutPermissionsNotRequestedByApp( packageName: String, userHandle: UserHandle @@ -228,6 +260,8 @@ class PermissionUsageViewModel( * Filters out system app permissions from a map of permission last accesses, if showSystem is * false. */ + @SuppressWarnings("NewApi") + // TODO : b/330215842 - Cleanup NewApi suppression's private fun Collection<Map.Entry<String, Long>>.filterOutSystemAppPermissionsIfNecessary( showSystem: Boolean, packageName: String, @@ -262,6 +296,8 @@ class PermissionUsageViewModel( * Returns from a list of permissions whether any permission along with the provided package * name and user handle are considered a system app permission. */ + @SuppressWarnings("NewApi") + // TODO : b/330215842 - Cleanup NewApi suppression's private fun Collection<String>.containsSystemAppPermission( packageName: String, userHandle: UserHandle @@ -291,7 +327,7 @@ class PermissionUsageViewModel( /** LiveData object for [PermissionUsagesUiData]. */ val permissionUsagesUiLiveData = - object : SmartUpdateMediatorLiveData<@JvmSuppressWildcards PermissionUsagesUiData>() { + object : SmartUpdateMediatorLiveData<@JvmSuppressWildcards PermissionUsagesUiState>() { private val getAppPermGroupUiInfoLiveData = { appPermissionId: AppPermissionId -> AppPermGroupUiInfoLiveData[ Triple( @@ -306,11 +342,11 @@ class PermissionUsageViewModel( init { addSource(mAllLightPackageOpsLiveData) { update() } - addSource(showSystemAppsLiveData) { update() } - addSource(show7DaysLiveData) { update() } addSource(standardPermGroupNamesLiveData) { update() } } + @SuppressWarnings("NewApi") + // TODO : b/330215842 - Cleanup NewApi suppression's override fun onUpdate() { if (mAllLightPackageOpsLiveData.isStale) { return diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionGroupsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionGroupsViewModel.kt index 5ecab1527..ee0c5d2f2 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionGroupsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionGroupsViewModel.kt @@ -46,6 +46,7 @@ import com.android.permissioncontroller.permission.data.PackagePermissionsLiveDa import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData.Companion.NON_RUNTIME_NORMAL_PERMS import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData import com.android.permissioncontroller.permission.data.get +import com.android.permissioncontroller.permission.data.v35.PackagePermissionsExternalDeviceLiveData import com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo.PermGrantState import com.android.permissioncontroller.permission.model.v31.AppPermissionUsage import com.android.permissioncontroller.permission.ui.Category @@ -55,6 +56,7 @@ import com.android.permissioncontroller.permission.utils.PermissionMapping import com.android.permissioncontroller.permission.utils.Utils import com.android.permissioncontroller.permission.utils.Utils.AppPermsLastAccessType import com.android.permissioncontroller.permission.utils.navigateSafe +import com.android.permissioncontroller.permission.utils.v35.MultiDeviceUtils import java.time.Instant import java.util.concurrent.TimeUnit import kotlin.math.max @@ -93,12 +95,29 @@ class AppPermissionGroupsViewModel( data class GroupUiInfo( val groupName: String, val isSystem: Boolean = false, - val subtitle: PermSubtitle + val subtitle: PermSubtitle, + val persistentDeviceId: String, ) { constructor( groupName: String, isSystem: Boolean - ) : this(groupName, isSystem, PermSubtitle.NONE) + ) : this( + groupName, + isSystem, + PermSubtitle.NONE, + MultiDeviceUtils.getDefaultDevicePersistentDeviceId() + ) + + constructor( + groupName: String, + isSystem: Boolean, + subtitle: PermSubtitle, + ) : this( + groupName, + isSystem, + subtitle, + MultiDeviceUtils.getDefaultDevicePersistentDeviceId() + ) } // Auto-revoke and hibernation share the same settings @@ -107,6 +126,8 @@ class AppPermissionGroupsViewModel( private val packagePermsLiveData = PackagePermissionsLiveData[packageName, user] private val appPermGroupUiInfoLiveDatas = mutableMapOf<String, AppPermGroupUiInfoLiveData>() private val fullStoragePermsLiveData = FullStoragePermissionAppsLiveData + private val packagePermsExternalDeviceLiveData = + PackagePermissionsExternalDeviceLiveData[packageName, user] /** * LiveData whose data is a map of grant category (either allowed or denied) to a list of @@ -124,6 +145,7 @@ class AppPermissionGroupsViewModel( removeSource(autoRevokeLiveData) update() } + addSource(packagePermsExternalDeviceLiveData) { update() } update() } @@ -217,6 +239,61 @@ class AppPermissionGroupsViewModel( } } + packagePermsExternalDeviceLiveData.value?.forEach { externalDeviceGrantInfo -> + val groupName = externalDeviceGrantInfo.groupName + val isSystem = + PermissionMapping.getPlatformPermissionGroups().contains(groupName) + val persistentDeviceId = externalDeviceGrantInfo.persistentDeviceId + when (externalDeviceGrantInfo.permGrantState) { + PermGrantState.PERMS_ALLOWED -> { + groupGrantStates[Category.ALLOWED]!!.add( + GroupUiInfo( + groupName, + isSystem, + PermSubtitle.NONE, + persistentDeviceId + ) + ) + } + PermGrantState.PERMS_ALLOWED_ALWAYS -> + groupGrantStates[Category.ALLOWED]!!.add( + GroupUiInfo( + groupName, + isSystem, + PermSubtitle.BACKGROUND, + persistentDeviceId + ) + ) + PermGrantState.PERMS_ALLOWED_FOREGROUND_ONLY -> + groupGrantStates[Category.ALLOWED]!!.add( + GroupUiInfo( + groupName, + isSystem, + PermSubtitle.FOREGROUND_ONLY, + persistentDeviceId + ) + ) + PermGrantState.PERMS_DENIED -> + groupGrantStates[Category.DENIED]!!.add( + GroupUiInfo( + groupName, + isSystem, + PermSubtitle.NONE, + persistentDeviceId + ) + ) + PermGrantState.PERMS_ASK -> + groupGrantStates[Category.ASK]!!.add( + GroupUiInfo( + groupName, + isSystem, + PermSubtitle.NONE, + persistentDeviceId + ) + ) + } + } + value = groupGrantStates } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt index 971542e2b..af26d2cc6 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt @@ -55,6 +55,8 @@ import com.android.permissioncontroller.permission.data.LightAppPermGroupLiveDat import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData import com.android.permissioncontroller.permission.data.get import com.android.permissioncontroller.permission.data.v34.SafetyLabelInfoLiveData +import com.android.permissioncontroller.permission.data.v35.PackagePermissionsExternalDeviceLiveData +import com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission import com.android.permissioncontroller.permission.service.PermissionChangeStorageImpl @@ -82,6 +84,7 @@ import com.android.permissioncontroller.permission.utils.SafetyNetLogger import com.android.permissioncontroller.permission.utils.Utils import com.android.permissioncontroller.permission.utils.navigateSafe import com.android.permissioncontroller.permission.utils.v34.SafetyLabelUtils +import com.android.permissioncontroller.permission.utils.v35.MultiDeviceUtils import com.android.settingslib.RestrictedLockUtils import java.util.Random import kotlin.collections.component1 @@ -96,15 +99,16 @@ import kotlin.collections.component2 * @param permGroupName The name of the permission group this ViewModel represents * @param user The user of the package * @param sessionId A session ID used in logs to identify this particular session + * @param persistentDeviceId The external device identifier */ class AppPermissionViewModel( private val app: Application, private val packageName: String, private val permGroupName: String, private val user: UserHandle, - private val sessionId: Long + private val sessionId: Long, + private val persistentDeviceId: String ) : ViewModel() { - companion object { private val LOG_TAG = AppPermissionViewModel::class.java.simpleName private const val DEVICE_PROFILE_ROLE_PREFIX = "android.app.role" @@ -223,6 +227,7 @@ class AppPermissionViewModel( value = null } } + override fun onUpdate() { for (state in FullStoragePermissionAppsLiveData.value ?: return) { if (state.packageName == packageName && state.user == user) { @@ -252,6 +257,8 @@ class AppPermissionViewModel( LightAppPermGroupLiveData[packageName, permGroupName, user] private val mediaStorageSupergroupLiveData = mutableMapOf<String, LightAppPermGroupLiveData>() + private val packagePermissionsExternalDeviceLiveData = + PackagePermissionsExternalDeviceLiveData[packageName, user] init { addSource(appPermGroupLiveData) { appPermGroup -> @@ -287,6 +294,8 @@ class AppPermissionViewModel( } addSource(showPermissionRationaleLiveData) { update() } + + addSource(packagePermissionsExternalDeviceLiveData) { update() } } private fun onMediaPermGroupUpdate( @@ -302,8 +311,55 @@ class AppPermissionViewModel( } } + // TODO: b/328839130 (Merge this with default device implementation) + private fun getButtonStatesForExternalDevicePermission(): Map<ButtonType, ButtonState> { + val allowedForegroundState = ButtonState() + allowedForegroundState.isShown = true + + val askState = ButtonState() + askState.isShown = true + + val deniedState = ButtonState() + deniedState.isShown = true + + packagePermissionsExternalDeviceLiveData.value!! + .filter { + it.groupName == permGroupName && it.persistentDeviceId == persistentDeviceId + } + .map { it.permGrantState } + .forEach { + when (it) { + AppPermGroupUiInfo.PermGrantState.PERMS_ALLOWED_FOREGROUND_ONLY -> + allowedForegroundState.isChecked = true + AppPermGroupUiInfo.PermGrantState.PERMS_ASK -> askState.isChecked = true + AppPermGroupUiInfo.PermGrantState.PERMS_DENIED -> + deniedState.isChecked = true + else -> { + Log.e(LOG_TAG, "Unsupported PermGrantState=$it") + } + } + } + return mapOf( + ALLOW to ButtonState(), + ALLOW_ALWAYS to ButtonState(), + ALLOW_FOREGROUND to allowedForegroundState, + ASK_ONCE to ButtonState(), + ASK to askState, + DENY to deniedState, + DENY_FOREGROUND to ButtonState(), + LOCATION_ACCURACY to ButtonState(), + SELECT_PHOTOS to ButtonState() + ) + } + override fun onUpdate() { + if (!MultiDeviceUtils.isDefaultDeviceId(persistentDeviceId)) { + value = getButtonStatesForExternalDevicePermission() + return + } + val group = appPermGroupLiveData.value ?: return + for (mediaGroupLiveData in mediaStorageSupergroupLiveData.values) { if (!mediaGroupLiveData.isInitialized) { return @@ -417,7 +473,16 @@ class AppPermissionViewModel( askOneTimeState.isChecked = group.foreground.isGranted && group.isOneTime askOneTimeState.isShown = askOneTimeState.isChecked deniedState.isChecked = !group.foreground.isGranted && !group.isOneTime - + if ( + Utils.getApplicationEnhancedConfirmationRestrictedIntentAsUser( + user, + app, + packageName, + permGroupName + ) != null + ) { + allowedState.isEnabled = false + } if (group.foreground.isPolicyFixed || group.foreground.isSystemFixed) { allowedState.isEnabled = false askState.isEnabled = false @@ -501,6 +566,24 @@ class AppPermissionViewModel( } } + @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM, codename = "VanillaIceCream") + fun handleDisabledAllowButton(fragment: Fragment) { + if ( + lightAppPermGroup!!.foreground.isSystemFixed || + lightAppPermGroup!!.foreground.isPolicyFixed + ) + return + val restrictionIntent = + Utils.getApplicationEnhancedConfirmationRestrictedIntentAsUser( + user, + app, + packageName, + permGroupName + ) + ?: return + fragment.startActivity(restrictionIntent) + } + @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codename = "UpsideDownCake") private fun shouldShowPhotoPickerPromptForApp(group: LightAppPermGroup): Boolean { if ( @@ -706,6 +789,11 @@ class AppPermissionViewModel( val wasForegroundGranted = group.foreground.isGranted val wasBackgroundGranted = group.background.isGranted + if (!MultiDeviceUtils.isDefaultDeviceId(persistentDeviceId)) { + handleChangeForExternalDevice(group.permissions.keys, changeRequest, setOneTime) + return + } + if (LocationUtils.isLocationGroupAndProvider(context, permGroupName, packageName)) { val packageLabel = KotlinUtils.getPackageLabel(app, packageName, user) LocationUtils.showLocationDialog(context, packageLabel) @@ -927,6 +1015,42 @@ class AppPermissionViewModel( } } + /** + * Handles the permission change for external devices. The original method that handles + * permission change for the default device makes use of LightAppPermGroup. This data class is + * not available for external devices, hence this implementation makes use of persistentDeviceId + * specific methods. + * + * TODO: b/328839130 + */ + private fun handleChangeForExternalDevice( + permissions: Set<String>, + changeRequest: ChangeRequest, + setOneTime: Boolean + ) { + when (changeRequest) { + ChangeRequest.GRANT_FOREGROUND_ONLY -> + MultiDeviceUtils.grantRuntimePermissionsWithPersistentDeviceId( + app, + persistentDeviceId, + packageName, + permissions, + true + ) + ChangeRequest.REVOKE_BOTH -> + MultiDeviceUtils.revokeRuntimePermissionsWithPersistentDeviceId( + app, + persistentDeviceId, + packageName, + permissions, + !setOneTime, + setOneTime + ) + else -> Log.e(LOG_TAG, "Unsupported changeRequest=$changeRequest") + } + PackagePermissionsExternalDeviceLiveData[packageName, user].update() + } + private fun shouldClearOneTimeRevokedCompat(group: LightAppPermGroup): Boolean { return isPhotoPickerPromptEnabled() && permGroupName == READ_MEDIA_VISUAL && @@ -1315,16 +1439,41 @@ class AppPermissionViewModel( * @param permGroupName The name of the permission group this ViewModel represents * @param user The user of the package * @param sessionId A session ID used in logs to identify this particular session + * @param persistentDeviceId Indicates the device in the context of virtual devices */ class AppPermissionViewModelFactory( private val app: Application, private val packageName: String, private val permGroupName: String, private val user: UserHandle, - private val sessionId: Long + private val sessionId: Long, + private val persistentDeviceId: String ) : ViewModelProvider.Factory { + constructor( + app: Application, + packageName: String, + permGroupName: String, + user: UserHandle, + sessionId: Long + ) : this( + app, + packageName, + permGroupName, + user, + sessionId, + MultiDeviceUtils.getDefaultDevicePersistentDeviceId() + ) + override fun <T : ViewModel> create(modelClass: Class<T>): T { @Suppress("UNCHECKED_CAST") - return AppPermissionViewModel(app, packageName, permGroupName, user, sessionId) as T + return AppPermissionViewModel( + app, + packageName, + permGroupName, + user, + sessionId, + persistentDeviceId + ) + as T } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt index 91b94da9a..1261d1259 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt @@ -68,6 +68,7 @@ import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_ import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED_ONE_TIME import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_IGNORED import com.android.permissioncontroller.auto.DrivingDecisionReminderService +import com.android.permissioncontroller.ecm.EnhancedConfirmationStatsLogUtils import com.android.permissioncontroller.permission.data.LightAppPermGroupLiveData import com.android.permissioncontroller.permission.data.LightPackageInfoLiveData import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData @@ -1002,6 +1003,12 @@ class GrantPermissionsViewModel( safetyLabelInfoLiveData?.value?.safetyLabel, PermissionMapping.getGroupOfPlatformPermission(permission) ) + val isPackageRestrictedByEnhancedConfirmation = + EnhancedConfirmationStatsLogUtils.isPackageEcmRestricted( + app, + packageName, + packageInfo.uid + ) Log.i( LOG_TAG, @@ -1010,7 +1017,9 @@ class GrantPermissionsViewModel( "callingPackage=$packageName " + "permission=$permission " + "isImplicit=$isImplicit result=$result " + - "isPermissionRationaleShown=$isPermissionRationaleShown" + "isPermissionRationaleShown=$isPermissionRationaleShown" + + "isPackageRestrictedByEnhancedConfirmation=" + + "$isPackageRestrictedByEnhancedConfirmation" ) PermissionControllerStatsLog.write( @@ -1021,7 +1030,8 @@ class GrantPermissionsViewModel( permission, isImplicit, result, - isPermissionRationaleShown + isPermissionRationaleShown, + isPackageRestrictedByEnhancedConfirmation ) } @@ -1371,6 +1381,7 @@ class GrantPermissionsViewModel( companion object { const val APP_PERMISSION_REQUEST_CODE = 1 const val PHOTO_PICKER_REQUEST_CODE = 2 + const val ECM_REQUEST_CODE = 3 const val SAVED_REQUEST_CODE_KEY = "saved_request_code" private const val STATE_UNKNOWN = 0 private const val STATE_GRANTED = 1 diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt index 826e57ece..0d532e026 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt @@ -32,6 +32,7 @@ import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle import android.os.UserHandle +import android.os.UserManager import androidx.annotation.RequiresApi import androidx.lifecycle.AbstractSavedStateViewModelFactory import androidx.lifecycle.SavedStateHandle @@ -85,6 +86,8 @@ class PermissionUsageDetailsViewModel( private val roleManager = Utils.getSystemServiceSafe(application.applicationContext, RoleManager::class.java) + private val userManager = + Utils.getSystemServiceSafe(application.applicationContext, UserManager::class.java) /** Updates whether system app permissions usage should be displayed in the UI. */ fun updateShowSystemAppsToggle(showSystem: Boolean) { @@ -191,6 +194,7 @@ class PermissionUsageDetailsViewModel( ): List<AppPermissionAccessUiInfo> { return allLightHistoricalPackageOpsLiveData .getLightHistoricalPackageOps() + ?.filter { Utils.shouldShowInSettings(it.userHandle, userManager) } ?.flatMap { it.clusterAccesses(startTime, showSystem) } ?.sortedBy { -1 * it.discreteAccesses.first().accessTimeMs } ?.map { it.buildAppPermissionAccessUiInfo() } @@ -262,9 +266,8 @@ class PermissionUsageDetailsViewModel( private fun List<AppPermissionDiscreteAccessesWithLabel>.filterOutExemptAppPermissions( showSystem: Boolean ): List<AppPermissionDiscreteAccessesWithLabel> { - return this.filter { - !Utils.getExemptedPackages(roleManager).contains(it.appPermissionId.packageName) - } + val exemptedPackages = Utils.getExemptedPackages(roleManager) + return filter { !exemptedPackages.contains(it.appPermissionId.packageName) } .filter { it.appPermissionId.permissionGroup == permissionGroup } .filter { isPermissionRequestedByApp(it.appPermissionId) } .filter { showSystem || !isAppPermissionSystem(it.appPermissionId) } @@ -488,7 +491,8 @@ class PermissionUsageDetailsViewModel( ?.let { getPackageLabel( it.proxy!!.packageName!!, - UserHandle.getUserHandleForUid(it.proxy.uid)) + UserHandle.getUserHandleForUid(it.proxy.uid) + ) } /** Returns the attribution label for the permission access, if any. */ diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/viewmodel/BasePermissionUsageViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/viewmodel/BasePermissionUsageViewModel.kt new file mode 100644 index 000000000..198793278 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/viewmodel/BasePermissionUsageViewModel.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.viewmodel + +import android.app.Application +import android.content.Context +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData + +/** + * Base class for [PermissionUsageViewModel] and [PermissionUsageViewModelV2], V2 is the new + * implementation following app architecture and resolving live data framework shortcomings. Remove + * [PermissionUsageViewModel] and this base class once V2 is stable. + */ +abstract class BasePermissionUsageViewModel(app: Application) : AndroidViewModel(app) { + abstract fun getPermissionUsagesUiLiveData(): LiveData<PermissionUsagesUiState> + abstract fun getShowSystemApps(): Boolean + abstract fun getShow7DaysData(): Boolean + abstract fun updateShowSystem(showSystem: Boolean): PermissionUsagesUiState + abstract fun updateShow7Days(show7Days: Boolean): PermissionUsagesUiState + abstract fun getPermissionGroupLabel(context: Context, permissionGroup: String): String +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/viewmodel/PermissionUsageViewModelV2.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/viewmodel/PermissionUsageViewModelV2.kt new file mode 100644 index 000000000..c79af76e4 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/viewmodel/PermissionUsageViewModelV2.kt @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.viewmodel + +import android.app.Application +import android.content.Context +import android.os.Build +import android.os.Bundle +import androidx.annotation.RequiresApi +import androidx.annotation.VisibleForTesting +import androidx.lifecycle.AbstractSavedStateViewModelFactory +import androidx.lifecycle.LiveData +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import androidx.lifecycle.asLiveData +import androidx.lifecycle.viewModelScope +import androidx.savedstate.SavedStateRegistryOwner +import com.android.permissioncontroller.permission.data.repository.PermissionRepository +import com.android.permissioncontroller.permission.domain.model.PermissionGroupUsageModel +import com.android.permissioncontroller.permission.domain.usecase.GetPermissionGroupUsageUseCase +import com.android.permissioncontroller.permission.utils.KotlinUtils +import java.time.Instant +import java.util.concurrent.TimeUnit +import kotlin.math.max +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.runBlocking + +/** Privacy dashboard's new implementation. */ +class PermissionUsageViewModelV2( + val app: Application, + private val permissionRepository: PermissionRepository, + private val getPermissionUsageUseCase: GetPermissionGroupUsageUseCase, + scope: CoroutineScope? = null +) : BasePermissionUsageViewModel(app) { + private var showSystemApps = false + private var show7DaysData = false + private val coroutineScope = scope ?: viewModelScope + private val permissionGroupOpsFlow: StateFlow<List<PermissionGroupUsageModel>> by lazy { + getPermissionUsageUseCase() + .stateIn(coroutineScope, SharingStarted.WhileSubscribed(5000), emptyList()) + } + + @VisibleForTesting + fun getPermissionUsagesUiDataFlow(): Flow<PermissionUsagesUiState> { + return permissionGroupOpsFlow.map { permGroupUsages -> + buildPermissionUsagesUiState(permGroupUsages) + } + } + + override fun getPermissionUsagesUiLiveData(): LiveData<PermissionUsagesUiState> { + return getPermissionUsagesUiDataFlow() + .asLiveData(context = coroutineScope.coroutineContext + Dispatchers.Default) + } + + /** Get start time based on whether to show 24 hours or 7 days data. */ + private fun getStartTime(show7DaysData: Boolean): Long { + val curTime = System.currentTimeMillis() + val showPermissionUsagesDuration = + if (KotlinUtils.is7DayToggleEnabled() && show7DaysData) { + TIME_7_DAYS_DURATION + } else { + TIME_24_HOURS_DURATION + } + return max(curTime - showPermissionUsagesDuration, Instant.EPOCH.toEpochMilli()) + } + + /** Builds a [PermissionUsagesUiState] containing all data necessary to render the UI. */ + private fun buildPermissionUsagesUiState( + permissionGroupOps: List<PermissionGroupUsageModel> + ): PermissionUsagesUiState { + val startTime = getStartTime(show7DaysData) + val dashboardPermissionGroups = + permissionRepository.getPermissionGroupsForPrivacyDashboard() + val permissionUsageCountMap = HashMap<String, Int>(dashboardPermissionGroups.size) + for (permissionGroup in dashboardPermissionGroups) { + permissionUsageCountMap[permissionGroup] = 0 + } + + val permGroupOps = permissionGroupOps.filter { it.lastAccessTimestampMillis > startTime } + permGroupOps + .filter { showSystemApps || it.isUserSensitive } + .forEach { + permissionUsageCountMap[it.permissionGroup] = + permissionUsageCountMap.getOrDefault(it.permissionGroup, 0) + 1 + } + return PermissionUsagesUiState( + permGroupOps.any { !it.isUserSensitive }, + permissionUsageCountMap + ) + } + + override fun getShowSystemApps(): Boolean { + return showSystemApps + } + + override fun getShow7DaysData(): Boolean { + return show7DaysData + } + + override fun updateShowSystem(showSystem: Boolean): PermissionUsagesUiState { + showSystemApps = showSystem + return buildPermissionUsagesUiState(permissionGroupOpsFlow.value) + } + + override fun updateShow7Days(show7Days: Boolean): PermissionUsagesUiState { + show7DaysData = show7Days + return buildPermissionUsagesUiState(permissionGroupOpsFlow.value) + } + + private val permissionGroupLabels = mutableMapOf<String, String>() + + override fun getPermissionGroupLabel(context: Context, permissionGroup: String): String { + return runBlocking(coroutineScope.coroutineContext + Dispatchers.Default) { + permissionGroupLabels.getOrDefault( + permissionGroup, + permissionRepository.getPermissionGroupLabel(context, permissionGroup).toString() + ) + } + } + + /** Companion class for [PermissionUsageViewModelV2]. */ + companion object { + internal val LOG_TAG = PermissionUsageViewModelV2::class.java.simpleName + + private val TIME_7_DAYS_DURATION = TimeUnit.DAYS.toMillis(7) + private val TIME_24_HOURS_DURATION = TimeUnit.DAYS.toMillis(1) + } +} + +/** Data class to hold all the information required to configure the UI. */ +data class PermissionUsagesUiState( + val shouldShowSystemToggle: Boolean, + // Map instances for display in UI + val permissionGroupUsageCount: Map<String, Int>, +) + +/** Factory for [BasePermissionUsageViewModel]. */ +@RequiresApi(Build.VERSION_CODES.S) +class PermissionUsageViewModelFactory( + private val app: Application, + owner: SavedStateRegistryOwner, + defaultArgs: Bundle +) : AbstractSavedStateViewModelFactory(owner, defaultArgs) { + @Suppress("UNCHECKED_CAST") + override fun <T : ViewModel> create( + key: String, + modelClass: Class<T>, + handle: SavedStateHandle + ): T { + val permissionRepository = PermissionRepository.getInstance(app) + val permissionUsageUseCase = GetPermissionGroupUsageUseCase.create(app) + return PermissionUsageViewModelV2(app, permissionRepository, permissionUsageUseCase) as T + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/GrantPermissionsWearViewHandler.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/GrantPermissionsWearViewHandler.java index cc32c5f02..c9e9a2eb1 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/GrantPermissionsWearViewHandler.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/GrantPermissionsWearViewHandler.java @@ -168,7 +168,8 @@ public class GrantPermissionsWearViewHandler implements GrantPermissionsViewHand private void updateScreen() { mViewModel.getIconLiveData().setValue( mGroupIcon == null ? null : mGroupIcon.loadDrawable(mActivity)); - mViewModel.getGroupMessageLiveData().setValue(mGroupMessage.toString()); + mViewModel.getGroupMessageLiveData().setValue( + mGroupMessage == null ? "" : mGroupMessage.toString()); mViewModel.getDetailMessageLiveData().setValue(mDetailMessage); int numButtons = BUTTON_RES_ID_TO_NUM.size(); List<Boolean> buttonVisibilityList = Arrays.asList(new Boolean[NEXT_BUTTON]); diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java index fdeb2ed2a..5f23829b0 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java @@ -179,7 +179,10 @@ public class ReviewPermissionsWearFragment extends PreferenceFragmentCompat } else { preference.setEnabled(true); } - + if (preference.getParent() != null) { + // Remove first if already added. + preference.getParent().removePreference(preference); + } if (group.isReviewRequired()) { if (!isPackageUpdated) { // An app just being installed, which means all groups requiring reviews. diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionFragment.kt index c1ce14f03..3936e54d4 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionFragment.kt @@ -56,6 +56,7 @@ import com.android.permissioncontroller.permission.ui.v33.AdvancedConfirmDialogA import com.android.permissioncontroller.permission.ui.wear.model.AppPermissionConfirmDialogViewModel import com.android.permissioncontroller.permission.ui.wear.model.AppPermissionConfirmDialogViewModelFactory import com.android.permissioncontroller.permission.ui.wear.model.ConfirmDialogArgs +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme import com.android.permissioncontroller.permission.utils.KotlinUtils.getPermGroupLabel import com.android.settingslib.RestrictedLockUtils @@ -150,6 +151,7 @@ class WearAppPermissionFragment : Fragment(), ConfirmDialogShowingFragment { ViewModelProvider(this, AppPermissionConfirmDialogViewModelFactory()) .get(AppPermissionConfirmDialogViewModel::class.java) + @Suppress("ktlint:standard:max-line-length") val onLocationSwitchChanged: (Boolean) -> Unit = { checked -> run { val changeRequest = @@ -233,18 +235,20 @@ class WearAppPermissionFragment : Fragment(), ConfirmDialogShowingFragment { return ComposeView(activity).apply { setContent { - WearAppPermissionScreen( - permGroupLabel, - viewModel, - confirmDialogViewModel, - onLocationSwitchChanged, - onGrantedStateChanged, - onFooterClicked, - onConfirmDialogOkButtonClick, - onConfirmDialogCancelButtonClick, - onAdvancedConfirmDialogOkButtonClick, - onAdvancedConfirmDialogCancelButtonClick - ) + WearPermissionTheme { + WearAppPermissionScreen( + permGroupLabel, + viewModel, + confirmDialogViewModel, + onLocationSwitchChanged, + onGrantedStateChanged, + onFooterClicked, + onConfirmDialogOkButtonClick, + onConfirmDialogCancelButtonClick, + onAdvancedConfirmDialogOkButtonClick, + onAdvancedConfirmDialogCancelButtonClick + ) + } } } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsFragment.kt index a0703b10c..9b960dfb5 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsFragment.kt @@ -46,6 +46,7 @@ import com.android.permissioncontroller.permission.ui.wear.model.AppPermissionGr import com.android.permissioncontroller.permission.ui.wear.model.AppPermissionGroupsRevokeDialogViewModelFactory import com.android.permissioncontroller.permission.ui.wear.model.WearAppPermissionUsagesViewModel import com.android.permissioncontroller.permission.ui.wear.model.WearAppPermissionUsagesViewModelFactory +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme import com.android.permissioncontroller.permission.utils.KotlinUtils.is7DayToggleEnabled import java.time.Instant import java.util.concurrent.TimeUnit @@ -142,7 +143,9 @@ class WearAppPermissionGroupsFragment : Fragment(), PermissionsUsagesChangeCallb revokeDialogViewModel = revokeDialogViewModel ) - return ComposeView(activity).apply { setContent { WearAppPermissionGroupsScreen(helper) } } + return ComposeView(activity).apply { + setContent { WearPermissionTheme { WearAppPermissionGroupsScreen(helper) } } + } } override fun onPause() { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt index 0ccde86be..9529ac83a 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt @@ -142,25 +142,27 @@ class WearAppPermissionGroupsHelper( ): String { val grantSummary = getGrantSummary(category, groupUiInfo)?.let { context.getString(it) } ?: "" - if (!Flags.wearPrivacyDashboardEnabled()) { - return grantSummary - } - val accessSummary = - viewModel.getPreferenceSummary(groupUiInfo, context, lastAccessTime).let { + val summary = StringBuilder(grantSummary) + if (Flags.wearPrivacyDashboardEnabledReadOnly()) { + WearUtils.getPreferenceSummary(context, lastAccessTime).let { if (it.isNotEmpty()) { - System.lineSeparator() + it - } else { - it + summary.append(System.lineSeparator()).append(it) } } - return grantSummary + accessSummary + } + return summary.toString() } private fun getGrantSummary(category: Category?, groupUiInfo: GroupUiInfo): Int? { val subtitle = groupUiInfo.subtitle if (category != null) { when (category) { - Category.ALLOWED -> return R.string.allowed_header + Category.ALLOWED -> + return if (subtitle == PermSubtitle.BACKGROUND) { + R.string.allowed_always_header + } else { + R.string.allowed_header + } Category.ASK -> return R.string.ask_header Category.DENIED -> return R.string.denied_header else -> { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt index bc840bac9..0883666fc 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt @@ -35,7 +35,7 @@ import com.android.permissioncontroller.permission.ui.wear.model.RevokeDialogArg @Composable fun WearAppPermissionGroupsScreen(helper: WearAppPermissionGroupsHelper) { - val packagePermGroups = helper.viewModel.packagePermGroupsLiveData.observeAsState(emptyMap()) + val packagePermGroups = helper.viewModel.packagePermGroupsLiveData.observeAsState(null) val autoRevoke = helper.viewModel.autoRevokeLiveData.observeAsState(null) val appPermissionUsages = helper.wearViewModel.appPermissionUsages.observeAsState(emptyList()) val showRevokeDialog = helper.revokeDialogViewModel.showDialogLiveData.observeAsState(false) @@ -53,7 +53,7 @@ fun WearAppPermissionGroupsScreen(helper: WearAppPermissionGroupsHelper) { ) } - if (isLoading && packagePermGroups.value.isNotEmpty()) { + if (isLoading && !packagePermGroups.value.isNullOrEmpty()) { isLoading = false } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt index bec633fe7..ccbd51f7d 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt @@ -52,7 +52,7 @@ fun WearAppPermissionScreen( onAdvancedConfirmDialogOkButtonClick: (AdvancedConfirmDialogArgs) -> Unit, onAdvancedConfirmDialogCancelButtonClick: () -> Unit ) { - val buttonState = viewModel.buttonStateLiveData.observeAsState(emptyMap()) + val buttonState = viewModel.buttonStateLiveData.observeAsState(null) val detailResIds = viewModel.detailResIdLiveData.observeAsState(null) val admin = viewModel.showAdminSupportLiveData.observeAsState(null) var isLoading by remember { mutableStateOf(true) } @@ -84,7 +84,7 @@ fun WearAppPermissionScreen( onCancelButtonClick = onAdvancedConfirmDialogCancelButtonClick ) } - if (isLoading && buttonState.value.isNotEmpty()) { + if (isLoading && !buttonState.value.isNullOrEmpty()) { isLoading = false } } @@ -92,7 +92,7 @@ fun WearAppPermissionScreen( @Composable internal fun WearAppPermissionContent( title: String, - buttonState: Map<ButtonType, ButtonState>, + buttonState: Map<ButtonType, ButtonState>?, detailResIds: Pair<Int, Int?>?, admin: RestrictedLockUtils.EnforcedAdmin?, isLoading: Boolean, @@ -101,7 +101,7 @@ internal fun WearAppPermissionContent( onFooterClicked: (RestrictedLockUtils.EnforcedAdmin) -> Unit ) { ScrollableScreen(title = title, isLoading = isLoading) { - buttonState[ButtonType.LOCATION_ACCURACY]?.let { + buttonState?.get(ButtonType.LOCATION_ACCURACY)?.let { if (it.isShown) { item { ToggleChip( @@ -116,7 +116,7 @@ internal fun WearAppPermissionContent( } } for (buttonType in buttonTypeOrder) { - buttonState[buttonType]?.let { + buttonState?.get(buttonType)?.let { if (it.isShown) { item { ToggleChip( diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionsFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionsFragment.kt index 266159733..a9e83919f 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionsFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionsFragment.kt @@ -26,6 +26,7 @@ import androidx.lifecycle.ViewModelProvider import com.android.permissioncontroller.Constants import com.android.permissioncontroller.permission.ui.handheld.PermissionAppsFragment import com.android.permissioncontroller.permission.ui.model.ManageCustomPermissionsViewModel +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme class WearManageCustomPermissionsFragment : Fragment() { override fun onCreateView( @@ -52,7 +53,11 @@ class WearManageCustomPermissionsFragment : Fragment() { } return ComposeView(activity).apply { - setContent { WearManageCustomPermissionScreen(viewModel, onPermGroupClick) } + setContent { + WearPermissionTheme { + WearManageCustomPermissionScreen(viewModel, onPermGroupClick) + } + } } } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionsFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionsFragment.kt index a33c71975..16ed1f067 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionsFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionsFragment.kt @@ -27,6 +27,7 @@ import com.android.permissioncontroller.Constants import com.android.permissioncontroller.permission.ui.handheld.ManageCustomPermissionsFragment import com.android.permissioncontroller.permission.ui.handheld.PermissionAppsFragment import com.android.permissioncontroller.permission.ui.model.ManageStandardPermissionsViewModel +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme class WearManageStandardPermissionsFragment : Fragment() { override fun onCreateView( @@ -63,12 +64,14 @@ class WearManageStandardPermissionsFragment : Fragment() { return ComposeView(activity).apply { setContent { - WearManageStandardPermissionScreen( - viewModel, - onPermGroupClick, - onCustomPermGroupClick, - onAutoRevokeClick - ) + WearPermissionTheme { + WearManageStandardPermissionScreen( + viewModel, + onPermGroupClick, + onCustomPermGroupClick, + onAutoRevokeClick + ) + } } } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsHelper.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsHelper.kt index 559160b38..d14cdb620 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsHelper.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsHelper.kt @@ -28,7 +28,6 @@ import com.android.permissioncontroller.permission.ui.wear.model.WearAppPermissi import com.android.permissioncontroller.permission.utils.KotlinUtils import com.android.permissioncontroller.permission.utils.KotlinUtils.getPermGroupDescription import com.android.permissioncontroller.permission.utils.KotlinUtils.getPermGroupLabel -import com.android.permissioncontroller.permission.utils.Utils import com.android.settingslib.utils.applications.AppUtils import java.text.Collator import java.util.Random @@ -161,17 +160,8 @@ class WearPermissionAppsHelper( ) } val summary = - if (Flags.wearPrivacyDashboardEnabled()) { - lastAccessTime?.let { - viewModel.getPreferenceSummary( - application.resources, - Utils.getPermissionLastAccessSummaryTimestamp( - lastAccessTime, - application, - permGroupName - ) - ) - } + if (Flags.wearPrivacyDashboardEnabledReadOnly()) { + lastAccessTime?.let { WearUtils.getPreferenceSummary(application, lastAccessTime) } } else { null } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageFragment.kt index f8c305e0f..b98cb1473 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageFragment.kt @@ -26,8 +26,10 @@ import androidx.compose.ui.platform.ComposeView import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import com.android.permissioncontroller.Constants -import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageViewModel -import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageViewModel.PermissionUsageViewModelFactory +import com.android.permissioncontroller.permission.ui.viewmodel.BasePermissionUsageViewModel +import com.android.permissioncontroller.permission.ui.viewmodel.PermissionUsageViewModelFactory +import com.android.permissioncontroller.permission.ui.wear.model.WearPermissionUsageViewModel +import com.android.permissioncontroller.permission.ui.wear.model.WearPermissionUsageViewModelFactory /** * This is a condensed version of @@ -36,6 +38,7 @@ import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageV */ @RequiresApi(Build.VERSION_CODES.S) class WearPermissionUsageFragment : Fragment() { + lateinit var wearViewModel: WearPermissionUsageViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -45,11 +48,17 @@ class WearPermissionUsageFragment : Fragment() { arguments?.getLong(Constants.EXTRA_SESSION_ID) ?: Constants.INVALID_SESSION_ID val factory = PermissionUsageViewModelFactory(requireActivity().getApplication(), this, Bundle()) - val viewModel: PermissionUsageViewModel = - ViewModelProvider(this, factory).get(PermissionUsageViewModel::class.java) + val viewModel = + ViewModelProvider(this, factory).get(BasePermissionUsageViewModel::class.java) + wearViewModel = + ViewModelProvider(this, WearPermissionUsageViewModelFactory(viewModel)) + .get(WearPermissionUsageViewModel::class.java) + viewModel + .getPermissionUsagesUiLiveData() + .observe(this, wearViewModel::updatePermissionUsagesUiStateLiveData) return ComposeView(requireContext()).apply { - setContent { WearPermissionUsageScreen(sessionId, viewModel) } + setContent { WearPermissionUsageScreen(sessionId, viewModel, wearViewModel) } } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt index f155365d0..093cd5a3d 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt @@ -30,25 +30,35 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import com.android.permissioncontroller.R import com.android.permissioncontroller.permission.ui.handheld.v31.PermissionUsageControlPreference -import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageViewModel +import com.android.permissioncontroller.permission.ui.viewmodel.BasePermissionUsageViewModel import com.android.permissioncontroller.permission.ui.wear.elements.Chip import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen +import com.android.permissioncontroller.permission.ui.wear.model.WearPermissionUsageViewModel import java.text.Collator @RequiresApi(Build.VERSION_CODES.S) @Composable -fun WearPermissionUsageScreen(sessionId: Long, viewModel: PermissionUsageViewModel) { +fun WearPermissionUsageScreen( + sessionId: Long, + viewModel: BasePermissionUsageViewModel, + wearViewModel: WearPermissionUsageViewModel +) { val context = LocalContext.current - val permissionUsagesUiData = viewModel.permissionUsagesUiLiveData.observeAsState(null) - val showSystem = viewModel.showSystemAppsLiveData.observeAsState(false) - val show7Days = viewModel.show7DaysLiveData.observeAsState(false) + val permissionUsagesUiData = wearViewModel.permissionUsagesUiStateLiveData.observeAsState(null) + val showSystem = wearViewModel.showSystemAppsLiveData.observeAsState(false) + val show7Days = wearViewModel.show7DaysLiveData.observeAsState(false) var isLoading by remember { mutableStateOf(true) } - val hasSystemApps: Boolean = permissionUsagesUiData.value?.containsSystemAppUsages ?: false - val onShowSystemClick: (Boolean) -> Unit = { show -> run { viewModel.updateShowSystem(show) } } + val hasSystemApps: Boolean = permissionUsagesUiData.value?.shouldShowSystemToggle ?: false + val onShowSystemClick: (Boolean) -> Unit = { show -> + run { + wearViewModel.updatePermissionUsagesUiStateLiveData(viewModel.updateShowSystem(show)) + wearViewModel.showSystemAppsLiveData.value = viewModel.getShowSystemApps() + } + } val permissionGroupWithUsageCounts: Map<String, Int> = - permissionUsagesUiData.value?.permissionGroupsWithUsageCount ?: emptyMap() + permissionUsagesUiData.value?.permissionGroupUsageCount ?: emptyMap() val permissionGroupWithUsageCountsEntries: List<Map.Entry<String, Int>> = ArrayList<Map.Entry<String, Int>>(permissionGroupWithUsageCounts.entries) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsFragment.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsFragment.kt index 93813de08..64acfdd96 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsFragment.kt @@ -41,6 +41,7 @@ import com.android.permissioncontroller.permission.ui.model.UnusedAppsViewModel. import com.android.permissioncontroller.permission.ui.model.UnusedAppsViewModelFactory import com.android.permissioncontroller.permission.ui.wear.model.WearUnusedAppsViewModel import com.android.permissioncontroller.permission.ui.wear.model.WearUnusedAppsViewModel.UnusedAppChip +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme import com.android.permissioncontroller.permission.utils.KotlinUtils import com.android.settingslib.utils.applications.AppUtils import java.text.Collator @@ -131,7 +132,9 @@ class WearUnusedAppsFragment : Fragment() { updateWearViewModel(false) } - return ComposeView(activity).apply { setContent { WearUnusedAppsScreen(wearViewModel) } } + return ComposeView(activity).apply { + setContent { WearPermissionTheme { WearUnusedAppsScreen(wearViewModel) } } + } } private fun initUnusedAppsMap(): MutableMap<UnusedPeriod, MutableMap<String, UnusedAppChip>> { @@ -145,17 +148,18 @@ class WearUnusedAppsFragment : Fragment() { private fun updatePackages(categorizedPackages: Map<UnusedPeriod, List<UnusedPackageInfo>>) { // Remove stale unused app chips for (period in allPeriods) { - val it: MutableIterator<Map.Entry<String, UnusedAppChip>> = - unusedAppsMap[period]!!.entries.iterator() - while (it.hasNext()) { - val contains = - categorizedPackages[period]?.any { (pkgName, user, _) -> - val key = createKey(pkgName, user) - it.next().key == key - } - if (contains != true) { - it.remove() - } + val unUsedAppsInAPeriod = unusedAppsMap[period] ?: continue + val categorizedPackagesOfAPeriod = categorizedPackages[period] + if (categorizedPackagesOfAPeriod == null) { + unUsedAppsInAPeriod.clear() + continue + } + val categorizedPackageKeys = + categorizedPackagesOfAPeriod.map { createKey(it.packageName, it.user) } + // Do not remove apps that are still in the unused category + val keysToRemove = unUsedAppsInAPeriod.keys.filterNot { it in categorizedPackageKeys } + for (key in keysToRemove) { + unUsedAppsInAPeriod.remove(key) } } @@ -300,6 +304,13 @@ class WearUnusedAppsFragment : Fragment() { private fun updateWearViewModel(isLoading: Boolean) { wearViewModel.loadingLiveData.value = isLoading wearViewModel.unusedPeriodCategoryVisibilitiesLiveData.setValue(categoryVisibilities) - wearViewModel.unusedAppChipsLiveData.setValue(unusedAppsMap) + + // Need to copy to non mutable maps or compose will not update correctly + val map = mutableMapOf<UnusedPeriod, Map<String, UnusedAppChip>>() + for (period in allPeriods) { + map.put(period, unusedAppsMap[period]!!.toMap()) + } + + wearViewModel.unusedAppChipsLiveData.setValue(map.toMap()) } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt index 7c2487004..423fa7759 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt @@ -37,7 +37,7 @@ fun WearUnusedAppsScreen(viewModel: WearUnusedAppsViewModel) { viewModel.unusedPeriodCategoryVisibilitiesLiveData.observeAsState(emptyList()) val infoMsgCategoryVisibility = viewModel.infoMsgCategoryVisibilityLiveData.observeAsState(false) - val unusedAppChips = viewModel.unusedAppChipsLiveData.observeAsState(mutableMapOf()) + val unusedAppChips = viewModel.unusedAppChipsLiveData.observeAsState(mapOf()) ScrollableScreen( showTimeText = true, diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUtils.kt new file mode 100644 index 000000000..53d41f7f0 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUtils.kt @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.wear + +import android.content.Context +import android.text.format.DateFormat +import androidx.annotation.IntDef +import com.android.permissioncontroller.R +import java.time.ZonedDateTime +import java.time.temporal.ChronoUnit + +object WearUtils { + @Retention(AnnotationRetention.SOURCE) + @IntDef(value = [LAST_24H_TODAY, LAST_24H_YESTERDAY, LAST_7D, NOT_IN_LAST_7D]) + annotation class AppPermsLastAccessType + + const val LAST_24H_TODAY = 1 + const val LAST_24H_YESTERDAY = 2 + const val LAST_7D = 3 + const val NOT_IN_LAST_7D = 4 + + /** Get the preference summary in app permission groups and permission apps screens for Wear. */ + @JvmStatic + fun getPreferenceSummary(context: Context, lastAccessTime: Long?): String { + val summaryTimestamp = getPermissionLastAccessSummaryTimestamp(lastAccessTime, context) + val res = context.resources + return when (summaryTimestamp.second) { + LAST_24H_TODAY -> + res.getString(R.string.wear_app_perms_24h_access, summaryTimestamp.first) + LAST_24H_YESTERDAY -> + res.getString(R.string.wear_app_perms_24h_access_yest, summaryTimestamp.first) + LAST_7D -> + res.getString( + R.string.wear_app_perms_7d_access, + summaryTimestamp.third, + summaryTimestamp.first + ) + else -> "" + } + } + + @JvmStatic + private fun getPermissionLastAccessSummaryTimestamp( + lastAccessTime: Long?, + context: Context + ): Triple<String, Int, String> { + val midnightToday = + (ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS).toEpochSecond() * 1000L) + val midnightYesterday = + ZonedDateTime.now().minusDays(1).truncatedTo(ChronoUnit.DAYS).toEpochSecond() * 1000L + val isLastAccessToday = (lastAccessTime != null && midnightToday <= lastAccessTime) + val isLastAccessTodayOrYesterday = + (lastAccessTime != null && midnightYesterday <= lastAccessTime) + var lastAccessTimeFormatted = "" + var lastAccessDateFormatted = "" + @AppPermsLastAccessType var lastAccessType = NOT_IN_LAST_7D + if (lastAccessTime != null) { + lastAccessTimeFormatted = DateFormat.getTimeFormat(context).format(lastAccessTime) + lastAccessDateFormatted = DateFormat.getDateFormat(context).format(lastAccessTime) + lastAccessType = + if (isLastAccessToday) LAST_24H_TODAY + else if (isLastAccessTodayOrYesterday) LAST_24H_YESTERDAY else LAST_7D + } + return Triple(lastAccessTimeFormatted, lastAccessType, lastAccessDateFormatted) + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/AlertDialog.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/AlertDialog.kt index 06d8acaba..aa04cfad8 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/AlertDialog.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/AlertDialog.kt @@ -16,32 +16,40 @@ package com.android.permissioncontroller.permission.ui.wear.elements -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.Close +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.dp +import androidx.wear.compose.foundation.lazy.ScalingLazyListScope import androidx.wear.compose.foundation.lazy.ScalingLazyListState -import androidx.wear.compose.material.ButtonDefaults import androidx.wear.compose.material.Icon +import androidx.wear.compose.material.LocalTextStyle import androidx.wear.compose.material.MaterialTheme import androidx.wear.compose.material.Text import androidx.wear.compose.material.dialog.Alert import androidx.wear.compose.material.dialog.Dialog +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnDefaults +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState +import com.android.permissioncontroller.permission.ui.wear.elements.layout.rememberColumnState /** - * This component is an alternative to [Alert], providing the following: + * This component is an alternative to [AlertContent], providing the following: * - a convenient way of passing a title and a message; + * - additional content can be specified between the message and the buttons * - default positive and negative buttons; * - wrapped in a [Dialog]; */ @Composable -public fun AlertDialog( +fun AlertDialog( message: String, iconRes: Int? = null, onCancelButtonClick: () -> Unit, @@ -49,7 +57,7 @@ public fun AlertDialog( showDialog: Boolean, scalingLazyListState: ScalingLazyListState, modifier: Modifier = Modifier, - title: String = "", + title: String? = null, okButtonContentDescription: String = stringResource(android.R.string.ok), cancelButtonContentDescription: String = stringResource(android.R.string.cancel) ) { @@ -59,13 +67,12 @@ public fun AlertDialog( scrollState = scalingLazyListState, modifier = modifier ) { - Alert( + AlertContent( title = title, - iconRes = iconRes, - body = message, - scrollState = scalingLazyListState, - onCancelButtonClick = onCancelButtonClick, - onOKButtonClick = onOKButtonClick, + icon = { AlertIcon(iconRes) }, + message = message, + onCancel = onCancelButtonClick, + onOk = onOKButtonClick, okButtonContentDescription = okButtonContentDescription, cancelButtonContentDescription = cancelButtonContentDescription ) @@ -86,7 +93,7 @@ fun SingleButtonAlertDialog( showDialog: Boolean, scalingLazyListState: ScalingLazyListState, modifier: Modifier = Modifier, - title: String = "", + title: String? = null, buttonContentDescription: String = stringResource(android.R.string.ok) ) { Dialog( @@ -95,77 +102,97 @@ fun SingleButtonAlertDialog( scrollState = scalingLazyListState, modifier = modifier ) { - SingleButtonAlert( + AlertContent( title = title, - iconRes = iconRes, - body = message, - scrollState = scalingLazyListState, - onButtonClick = onButtonClick, - buttonContentDescription = buttonContentDescription + icon = { AlertIcon(iconRes) }, + message = message, + onOk = onButtonClick, + okButtonContentDescription = buttonContentDescription ) } } @Composable -internal fun Alert( - title: String, - iconRes: Int? = null, - body: String, - scrollState: ScalingLazyListState, - onCancelButtonClick: () -> Unit, - onOKButtonClick: () -> Unit, - okButtonContentDescription: String, - cancelButtonContentDescription: String +public fun AlertContent( + onCancel: (() -> Unit)? = null, + onOk: (() -> Unit)? = null, + icon: @Composable (() -> Unit)? = null, + title: String? = null, + message: String? = null, + okButtonContentDescription: String = stringResource(android.R.string.ok), + cancelButtonContentDescription: String = stringResource(android.R.string.cancel), + state: ScalingLazyColumnState = + rememberColumnState( + ScalingLazyColumnDefaults.responsive( + additionalPaddingAtBottom = 0.dp, + ), + ), + showPositionIndicator: Boolean = true, + content: (ScalingLazyListScope.() -> Unit)? = null, ) { - Alert( - contentPadding = DefaultContentPadding(), - scrollState = scrollState, - title = { AlertTitleText(title) }, - icon = { AlertIcon(iconRes) }, - content = { AlertBodyText(body) }, - negativeButton = { NegativeButton(onCancelButtonClick, cancelButtonContentDescription) }, - positiveButton = { PositiveButton(onOKButtonClick, okButtonContentDescription) } - ) -} + val density = LocalDensity.current + val maxScreenWidthPx = with(density) { LocalConfiguration.current.screenWidthDp.dp.toPx() } -@Composable -private fun SingleButtonAlert( - title: String, - iconRes: Int? = null, - body: String, - scrollState: ScalingLazyListState, - isOkButton: Boolean = true, - onButtonClick: () -> Unit, - buttonContentDescription: String, -) { - Alert( - contentPadding = DefaultContentPadding(), - title = { AlertTitleText(title) }, - scrollState = scrollState, - icon = { AlertIcon(iconRes) }, - message = { AlertBodyText(body) } - ) { - item { - if (isOkButton) { - PositiveButton(onButtonClick, buttonContentDescription) - } else { - NegativeButton(onButtonClick, buttonContentDescription) - } - } - } -} - -@Composable private fun DefaultContentPadding() = PaddingValues(top = 24.dp, bottom = 24.dp) - -@Composable -private fun AlertTitleText(title: String) = - Text( - text = title, - color = MaterialTheme.colors.onBackground, - textAlign = TextAlign.Center, - maxLines = 3, - style = MaterialTheme.typography.title3 + ResponsiveDialogContent( + icon = icon, + title = + title?.let { + { + Text( + modifier = Modifier.fillMaxWidth(), + text = it, + color = MaterialTheme.colors.onBackground, + textAlign = TextAlign.Center, + maxLines = if (icon == null) 3 else 2, + overflow = TextOverflow.Ellipsis, + ) + } + }, + message = + message?.let { + { + // Should message be start or center aligned? + val textMeasurer = rememberTextMeasurer() + val textStyle = LocalTextStyle.current + val totalPaddingPercentage = + globalHorizontalPadding + messageExtraHorizontalPadding + val lineCount = + remember(it, density, textStyle, textMeasurer) { + textMeasurer + .measure( + text = it, + style = textStyle, + constraints = + Constraints( + // Available width is reduced by responsive dialog + // horizontal + // padding. + maxWidth = + (maxScreenWidthPx * + (1f - totalPaddingPercentage * 2f / 100f)) + .toInt(), + ), + ) + .lineCount + } + val textAlign = if (lineCount <= 3) TextAlign.Center else TextAlign.Start + Text( + modifier = Modifier.fillMaxWidth(), + text = it, + color = MaterialTheme.colors.onBackground, + textAlign = textAlign, + ) + } + }, + content = content, + onOk = onOk, + onCancel = onCancel, + okButtonContentDescription = okButtonContentDescription, + cancelButtonContentDescription = cancelButtonContentDescription, + state = state, + showPositionIndicator = showPositionIndicator, ) +} @Composable private fun AlertIcon(iconRes: Int?) = @@ -174,29 +201,3 @@ private fun AlertIcon(iconRes: Int?) = } else { null } - -@Composable -private fun AlertBodyText(body: String) = - Text( - text = body, - color = MaterialTheme.colors.onBackground, - textAlign = TextAlign.Center, - style = MaterialTheme.typography.body2 - ) - -@Composable -private fun PositiveButton(onClick: () -> Unit, contentDescription: String) = - Button( - imageVector = Icons.Default.Check, - contentDescription = contentDescription, - onClick = onClick - ) - -@Composable -private fun NegativeButton(onClick: () -> Unit, contentDescription: String) = - Button( - imageVector = Icons.Default.Close, - contentDescription = contentDescription, - onClick = onClick, - colors = ButtonDefaults.secondaryButtonColors() - ) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Chip.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Chip.kt index abdbe4baf..bf9ebbadd 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Chip.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Chip.kt @@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -232,7 +233,8 @@ public fun Chip( icon = icon, colors = colors, enabled = enabled, - contentPadding = contentPadding + contentPadding = contentPadding, + shape = RoundedCornerShape(26.dp) ) } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListHeader.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListHeader.kt index cd5f3eb8f..0afbb05fe 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListHeader.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListHeader.kt @@ -67,7 +67,6 @@ fun ListHeader( modifier = modifier .defaultMinSize(minHeight = ListHeaderDefaults.Height) - .height(IntrinsicSize.Min) .wrapContentSize() .background(backgroundColor) .padding(contentPadding) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ResponsiveDialog.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ResponsiveDialog.kt new file mode 100644 index 000000000..cf828b91d --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ResponsiveDialog.kt @@ -0,0 +1,226 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.wear.elements + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Arrangement.spacedBy +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Close +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.wear.compose.foundation.lazy.ScalingLazyListScope +import androidx.wear.compose.material.ButtonDefaults +import androidx.wear.compose.material.ChipColors +import androidx.wear.compose.material.ChipDefaults +import androidx.wear.compose.material.LocalTextStyle +import androidx.wear.compose.material.MaterialTheme +import androidx.wear.compose.material.PositionIndicator +import androidx.wear.compose.material.Scaffold +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumn +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnDefaults.responsive +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState +import com.android.permissioncontroller.permission.ui.wear.elements.layout.rememberColumnState + +// This file is a copy of ResponsiveDialogContent.kt from Horologist (go/horologist), +// remove it once after wear compose supports large screen dialogs. + +@Composable +fun ResponsiveDialogContent( + modifier: Modifier = Modifier, + icon: @Composable (() -> Unit)? = null, + title: @Composable (() -> Unit)? = null, + message: @Composable (() -> Unit)? = null, + onOk: (() -> Unit)? = null, + onCancel: (() -> Unit)? = null, + okButtonContentDescription: String = stringResource(android.R.string.ok), + cancelButtonContentDescription: String = stringResource(android.R.string.cancel), + state: ScalingLazyColumnState = + rememberColumnState( + responsive( + firstItemIsFullWidth = icon == null, + additionalPaddingAtBottom = 0.dp, + ), + ), + showPositionIndicator: Boolean = true, + content: (ScalingLazyListScope.() -> Unit)? = null, +) { + Scaffold( + modifier = modifier.fillMaxSize(), + positionIndicator = { + if (showPositionIndicator) { + PositionIndicator(scalingLazyListState = state.state) + } + }, + timeText = {}, + ) { + // This will be applied only to the content. + CompositionLocalProvider( + LocalTextStyle provides MaterialTheme.typography.body2, + ) { + ScalingLazyColumn(columnState = state) { + icon?.let { + item { + Row( + Modifier.fillMaxWidth().padding(bottom = 4.dp), // 8.dp below icon + horizontalArrangement = Arrangement.Center, + ) { + it() + } + } + } + title?.let { + item { + CompositionLocalProvider( + LocalTextStyle provides MaterialTheme.typography.title3, + ) { + Box( + Modifier.fillMaxWidth(titleMaxWidthFraction) + .padding(bottom = 8.dp), // 12.dp below icon + ) { + it() + } + } + } + } + if (icon == null && title == null) { + // Ensure the content is visible when there is nothing above it. + item { Spacer(Modifier.height(20.dp)) } + } + message?.let { + item { + Box( + Modifier.fillMaxWidth(messageMaxWidthFraction), + ) { + it() + } + } + } + content?.let { it() } + if (onOk != null || onCancel != null) { + item { + val width = LocalConfiguration.current.screenWidthDp + // Single buttons, or buttons on smaller screens are not meant to be + // responsive. + val buttonWidth = + if (width < 225 || onOk == null || onCancel == null) { + ButtonDefaults.DefaultButtonSize + } else { + // 14.56% on top of 5.2% margin on the sides, 12.dp between. + ((width * (1f - (2 * 0.1456f) - (2 * 0.052f)) - 12) / 2).dp + } + Row( + Modifier.fillMaxWidth() + .padding( + top = if (content != null || message != null) 12.dp else 0.dp, + ), + horizontalArrangement = spacedBy(12.dp, Alignment.CenterHorizontally), + verticalAlignment = Alignment.CenterVertically, + ) { + onCancel?.let { + ResponsiveButton( + icon = Icons.Default.Close, + cancelButtonContentDescription, + onClick = it, + buttonWidth, + ChipDefaults.secondaryChipColors(), + ) + } + onOk?.let { + ResponsiveButton( + icon = Icons.Default.Check, + okButtonContentDescription, + onClick = it, + buttonWidth, + ) + } + } + } + } + } + } + } +} + +@Composable +private fun ResponsiveButton( + icon: ImageVector, + contentDescription: String, + onClick: () -> Unit, + buttonWidth: Dp, + colors: ChipColors = ChipDefaults.primaryChipColors(), +) { + androidx.wear.compose.material.Chip( + label = { + Box(Modifier.fillMaxWidth()) { + Icon( + imageVector = icon, + contentDescription = contentDescription, + modifier = + Modifier.size(ButtonDefaults.DefaultIconSize).align(Alignment.Center), + ) + } + }, + contentPadding = PaddingValues(0.dp), + shape = CircleShape, + onClick = onClick, + modifier = Modifier.width(buttonWidth), + colors = colors, + ) +} + +internal const val globalHorizontalPadding = 5.2f +internal const val messageExtraHorizontalPadding = 4.56f +internal const val titleExtraHorizontalPadding = 8.84f + +// Fraction of the max available width that message should take (after global and message padding) +internal val messageMaxWidthFraction = + 1f - + 2f * + calculatePaddingFraction( + messageExtraHorizontalPadding, + ) + +// Fraction of the max available width that title should take (after global and message padding) +internal val titleMaxWidthFraction = + 1f - + 2f * + calculatePaddingFraction( + titleExtraHorizontalPadding, + ) + +// Calculate total padding given global padding and additional padding required inside that. +internal fun calculatePaddingFraction(extraPadding: Float) = + extraPadding / (100f - 2f * globalHorizontalPadding) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt index 4228135f6..ed4e937d1 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt @@ -21,8 +21,6 @@ import android.content.Context import android.content.ContextWrapper import android.graphics.drawable.Drawable import androidx.compose.foundation.Image -import androidx.compose.foundation.focusable -import androidx.compose.foundation.gestures.scrollBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize @@ -33,22 +31,19 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.input.rotary.onRotaryScrollEvent import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Lifecycle @@ -68,7 +63,8 @@ import androidx.wear.compose.material.TimeText import androidx.wear.compose.material.Vignette import androidx.wear.compose.material.VignettePosition import androidx.wear.compose.material.scrollAway -import kotlinx.coroutines.launch +import com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput.rotaryWithScroll +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme /** * Screen that contains a list of items defined using the [content] parameter, adds the time text @@ -142,30 +138,28 @@ internal fun Scaffold( ) { val initialCenterIndex = 0 val scrollContentTopPadding = 32.dp + val centerHeightDp = Dp(LocalConfiguration.current.screenHeightDp / 2.0f) + val initialCenterItemScrollOffset = scrollContentTopPadding + 10.dp + val scrollAwayOffset = centerHeightDp - initialCenterItemScrollOffset + val focusRequester = remember { FocusRequester() } val listState = remember { ScalingLazyListState(initialCenterItemIndex = initialCenterIndex) } - val coroutineScope = rememberCoroutineScope() - MaterialTheme { + WearPermissionTheme { Scaffold( + // TODO: Use a rotary modifier from Wear Compose once Wear Compose 1.4 is landed. + // (b/325560444) modifier = - Modifier.onRotaryScrollEvent { - coroutineScope.launch { listState.scrollBy(it.verticalScrollPixels) } - true - } - .focusRequester(focusRequester) - .focusable() - .semantics { testTagsAsResourceId = true }, + Modifier.rotaryWithScroll( + scrollableState = listState, + focusRequester = focusRequester + ), timeText = { if (showTimeText && !isLoading) { TimeText( modifier = - Modifier.scrollAway( - listState, - initialCenterIndex, - scrollContentTopPadding - ), - contentPadding = PaddingValues(15.dp) + Modifier.scrollAway(listState, initialCenterIndex, scrollAwayOffset), + contentPadding = PaddingValues(5.dp) ) } }, diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnDefaults.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnDefaults.kt new file mode 100644 index 000000000..550f1dc24 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnDefaults.kt @@ -0,0 +1,245 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("ObjectLiteralToLambda") + +package com.android.permissioncontroller.permission.ui.wear.elements.layout + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.times +import androidx.compose.ui.util.lerp +import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults +import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType +import androidx.wear.compose.foundation.lazy.ScalingParams +import androidx.wear.compose.material.ChipDefaults +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState.RotaryMode +import kotlin.math.sqrt + +// This file's content is copied from ScalingLazyColumnDefaults.kt from Horologist (go/horologist), +// remove it once after wear compose supports large screen dialogs. + +/** Default layouts for ScalingLazyColumnState, based on UX guidance. */ +object ScalingLazyColumnDefaults { + + /** + * Creates a Responsive layout for ScalingLazyColumn. The first and last items will scroll just + * onto screen at full size, assuming rounded corners of a Chip. + * + * @param firstItemIsFullWidth set to false if the first item is small enough to fit at the top, + * however it may be scaled. + * @param additionalPaddingAtBottom additional padding at end of content to avoid problem items + * clipping + * @param verticalArrangement the ScalingLazyColumn verticalArrangement. + * @param horizontalPaddingPercent the amount of horizontal padding as a percent. + * @param rotaryMode the rotary handling, such as Fling or Snap. + * @param hapticsEnabled whether haptics are enabled. + * @param reverseLayout whether to start at the bottom. + * @param userScrollEnabled whether to allow user to scroll. + */ + // @Deprecated("Replaced by rememberResponsiveColumnState") + + fun responsive( + firstItemIsFullWidth: Boolean = true, + additionalPaddingAtBottom: Dp = 10.dp, + verticalArrangement: Arrangement.Vertical = + Arrangement.spacedBy( + space = 4.dp, + alignment = Alignment.Top, + ), + horizontalPaddingPercent: Float = 0.052f, + rotaryMode: RotaryMode? = RotaryMode.Scroll, + hapticsEnabled: Boolean = true, + reverseLayout: Boolean = false, + userScrollEnabled: Boolean = true, + ): ScalingLazyColumnState.Factory { + return object : ScalingLazyColumnState.Factory { + @Composable + override fun create(): ScalingLazyColumnState { + val density = LocalDensity.current + val configuration = LocalConfiguration.current + val screenWidthDp = configuration.screenWidthDp.toFloat() + val screenHeightDp = configuration.screenHeightDp.toFloat() + + return remember { + val padding = screenWidthDp * horizontalPaddingPercent + val topPaddingDp: Dp = + if (firstItemIsFullWidth && configuration.isScreenRound) { + calculateVerticalOffsetForChip(screenWidthDp, horizontalPaddingPercent) + } else { + 32.dp + } + val bottomPaddingDp: Dp = + if (configuration.isScreenRound) { + calculateVerticalOffsetForChip( + screenWidthDp, + horizontalPaddingPercent, + ) + additionalPaddingAtBottom + } else { + 0.dp + } + val contentPadding = + PaddingValues( + start = padding.dp, + end = padding.dp, + top = topPaddingDp, + bottom = bottomPaddingDp, + ) + + val scalingParams = responsiveScalingParams(screenWidthDp) + + val screenHeightPx = with(density) { screenHeightDp.dp.roundToPx() } + val topPaddingPx = with(density) { topPaddingDp.roundToPx() } + val topScreenOffsetPx = screenHeightPx / 2 - topPaddingPx + + val initialScrollPosition = + ScalingLazyColumnState.ScrollPosition( + index = 0, + offsetPx = topScreenOffsetPx, + ) + ScalingLazyColumnState( + initialScrollPosition = initialScrollPosition, + autoCentering = null, + anchorType = ScalingLazyListAnchorType.ItemStart, + rotaryMode = rotaryMode, + verticalArrangement = verticalArrangement, + horizontalAlignment = Alignment.CenterHorizontally, + contentPadding = contentPadding, + scalingParams = scalingParams, + hapticsEnabled = hapticsEnabled, + reverseLayout = reverseLayout, + userScrollEnabled = userScrollEnabled, + ) + } + } + } + } + + internal fun calculateVerticalOffsetForChip( + viewportDiameter: Float, + horizontalPaddingPercent: Float, + ): Dp { + val childViewHeight: Float = ChipDefaults.Height.value + val childViewWidth: Float = viewportDiameter * (1.0f - (2f * horizontalPaddingPercent)) + val radius = viewportDiameter / 2f + return (radius - + sqrt( + (radius - childViewHeight + childViewWidth * 0.5f) * + (radius - childViewWidth * 0.5f), + ) - + childViewHeight * 0.5f) + .dp + } + + fun responsiveScalingParams(screenWidthDp: Float): ScalingParams { + val sizeRatio = ((screenWidthDp - 192) / (233 - 192).toFloat()).coerceIn(0f, 1.5f) + val presetRatio = 0f + + val minElementHeight = lerp(0.2f, 0.157f, sizeRatio) + val maxElementHeight = lerp(0.6f, 0.472f, sizeRatio).coerceAtLeast(minElementHeight) + val minTransitionArea = lerp(0.35f, lerp(0.35f, 0.393f, presetRatio), sizeRatio) + val maxTransitionArea = lerp(0.55f, lerp(0.55f, 0.593f, presetRatio), sizeRatio) + + val scalingParams = + ScalingLazyColumnDefaults.scalingParams( + minElementHeight = minElementHeight, + maxElementHeight = maxElementHeight, + minTransitionArea = minTransitionArea, + maxTransitionArea = maxTransitionArea, + ) + return scalingParams + } + + internal val Padding12Pct = 0.1248f + internal val Padding16Pct = 0.1664f + internal val Padding20Pct = 0.2083f + internal val Padding21Pct = 0.2188f + internal val Padding31Pct = 0.3646f + + enum class ItemType( + val topPaddingDp: Float, + val bottomPaddingDp: Float, + val paddingCorrection: Dp = 0.dp, + ) { + Card(Padding21Pct, Padding31Pct), + Chip(Padding21Pct, Padding31Pct), + CompactChip( + topPaddingDp = Padding12Pct, + bottomPaddingDp = Padding20Pct, + paddingCorrection = (-8).dp, + ), + Icon(Padding12Pct, Padding21Pct), + MultiButton(Padding21Pct, Padding20Pct), + SingleButton(Padding12Pct, Padding20Pct), + Text(Padding21Pct, Padding31Pct), + Unspecified(0f, 0f), + } + + @Composable + fun padding( + first: ItemType = ItemType.Unspecified, + last: ItemType = ItemType.Unspecified, + horizontalPercent: Float = 0.052f, + ): @Composable () -> PaddingValues { + val configuration = LocalConfiguration.current + val screenWidthDp = configuration.screenWidthDp.toFloat() + val screenHeightDp = configuration.screenHeightDp.toFloat() + + return { + val height = screenHeightDp.dp + val horizontalPadding = screenWidthDp.dp * horizontalPercent + + val topPadding = + if (first != ItemType.Unspecified) { + first.topPaddingDp * height + first.paddingCorrection + } else { + if (configuration.isScreenRound) { + calculateVerticalOffsetForChip(screenWidthDp, horizontalPercent) + } else { + 32.dp + } + } + + val bottomPadding = + if (last != ItemType.Unspecified) { + last.bottomPaddingDp * height + first.paddingCorrection + } else { + if (configuration.isScreenRound) { + calculateVerticalOffsetForChip( + screenWidthDp, + horizontalPercent, + ) + 10.dp + } else { + 0.dp + } + } + + PaddingValues( + top = topPadding, + bottom = bottomPadding, + start = horizontalPadding, + end = horizontalPadding, + ) + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnState.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnState.kt new file mode 100644 index 000000000..0603647b1 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnState.kt @@ -0,0 +1,249 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("ObjectLiteralToLambda") +@file:OptIn(ExperimentalWearFoundationApi::class) + +package com.android.permissioncontroller.permission.ui.wear.elements.layout + +import androidx.compose.foundation.MutatePriority +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.gestures.ScrollScope +import androidx.compose.foundation.gestures.ScrollableDefaults +import androidx.compose.foundation.gestures.ScrollableState +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import androidx.wear.compose.foundation.ExperimentalWearFoundationApi +import androidx.wear.compose.foundation.lazy.AutoCenteringParams +import androidx.wear.compose.foundation.lazy.ScalingLazyColumn +import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults as WearScalingLazyColumnDefaults +import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType +import androidx.wear.compose.foundation.lazy.ScalingLazyListScope +import androidx.wear.compose.foundation.lazy.ScalingLazyListState +import androidx.wear.compose.foundation.lazy.ScalingParams +import androidx.wear.compose.foundation.rememberActiveFocusRequester +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnDefaults.responsiveScalingParams +import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState.RotaryMode +import com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput.rememberDisabledHaptic +import com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput.rememberRotaryHapticHandler +import com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput.rotaryWithScroll +import com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput.rotaryWithSnap +import com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput.toRotaryScrollAdapter + +// This file is a copy of ScalingLazyColumnState.kt from Horologist (go/horologist), +// remove it once after wear compose supports large screen dialogs. + +/** + * A Config and State object wrapping up all configuration for a [ScalingLazyColumn]. This allows + * defaults such as [ScalingLazyColumnDefaults.responsive]. + */ +class ScalingLazyColumnState( + val initialScrollPosition: ScrollPosition = ScrollPosition(1, 0), + val autoCentering: AutoCenteringParams? = + AutoCenteringParams( + initialScrollPosition.index, + initialScrollPosition.offsetPx, + ), + val anchorType: ScalingLazyListAnchorType = ScalingLazyListAnchorType.ItemCenter, + val contentPadding: PaddingValues = PaddingValues(horizontal = 10.dp), + val rotaryMode: RotaryMode? = RotaryMode.Scroll, + val reverseLayout: Boolean = false, + val verticalArrangement: Arrangement.Vertical = + Arrangement.spacedBy( + space = 4.dp, + alignment = if (!reverseLayout) Alignment.Top else Alignment.Bottom, + ), + val horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally, + val flingBehavior: FlingBehavior? = null, + val userScrollEnabled: Boolean = true, + val scalingParams: ScalingParams = WearScalingLazyColumnDefaults.scalingParams(), + val hapticsEnabled: Boolean = true, +) : ScrollableState { + private var _state: ScalingLazyListState? = null + var state: ScalingLazyListState + get() { + if (_state == null) { + _state = + ScalingLazyListState( + initialScrollPosition.index, + initialScrollPosition.offsetPx, + ) + } + return _state!! + } + set(value) { + _state = value + } + + override val canScrollBackward: Boolean + get() = state.canScrollBackward + + override val canScrollForward: Boolean + get() = state.canScrollForward + + override val isScrollInProgress: Boolean + get() = state.isScrollInProgress + + override fun dispatchRawDelta(delta: Float): Float = state.dispatchRawDelta(delta) + + override suspend fun scroll( + scrollPriority: MutatePriority, + block: suspend ScrollScope.() -> Unit, + ) { + state.scroll(scrollPriority, block) + } + + sealed interface RotaryMode { + data object Snap : RotaryMode + + data object Scroll : RotaryMode + } + + data class ScrollPosition( + val index: Int, + val offsetPx: Int, + ) + + fun interface Factory { + @Composable fun create(): ScalingLazyColumnState + } +} + +// @Deprecated("Replaced by rememberResponsiveColumnState") +@Composable +fun rememberColumnState( + factory: ScalingLazyColumnState.Factory = ScalingLazyColumnDefaults.responsive(), +): ScalingLazyColumnState { + val columnState = factory.create() + + columnState.state = rememberSaveable(saver = ScalingLazyListState.Saver) { columnState.state } + + return columnState +} + +@Composable +fun rememberResponsiveColumnState( + contentPadding: @Composable () -> PaddingValues = + ScalingLazyColumnDefaults.padding( + first = ScalingLazyColumnDefaults.ItemType.Unspecified, + last = ScalingLazyColumnDefaults.ItemType.Unspecified, + ), + verticalArrangement: Arrangement.Vertical = + Arrangement.spacedBy( + space = 4.dp, + alignment = Alignment.Top, + ), + rotaryMode: RotaryMode? = RotaryMode.Scroll, + hapticsEnabled: Boolean = true, + reverseLayout: Boolean = false, + userScrollEnabled: Boolean = true, +): ScalingLazyColumnState { + val density = LocalDensity.current + val configuration = LocalConfiguration.current + val screenWidthDp = configuration.screenWidthDp.toFloat() + val screenHeightDp = configuration.screenHeightDp.toFloat() + + val scalingParams = responsiveScalingParams(screenWidthDp) + + val contentPaddingCalculated = contentPadding() + + val screenHeightPx = with(density) { screenHeightDp.dp.roundToPx() } + val topPaddingPx = with(density) { contentPaddingCalculated.calculateTopPadding().roundToPx() } + val topScreenOffsetPx = screenHeightPx / 2 - topPaddingPx + + val initialScrollPosition = + ScalingLazyColumnState.ScrollPosition( + index = 0, + offsetPx = topScreenOffsetPx, + ) + + val columnState = + ScalingLazyColumnState( + initialScrollPosition = initialScrollPosition, + autoCentering = null, + anchorType = ScalingLazyListAnchorType.ItemStart, + rotaryMode = rotaryMode, + verticalArrangement = verticalArrangement, + horizontalAlignment = Alignment.CenterHorizontally, + contentPadding = contentPaddingCalculated, + scalingParams = scalingParams, + hapticsEnabled = hapticsEnabled, + reverseLayout = reverseLayout, + userScrollEnabled = userScrollEnabled, + ) + + columnState.state = rememberSaveable(saver = ScalingLazyListState.Saver) { columnState.state } + + return columnState +} + +@Composable +fun ScalingLazyColumn( + columnState: ScalingLazyColumnState, + modifier: Modifier = Modifier, + content: ScalingLazyListScope.() -> Unit, +) { + val focusRequester = rememberActiveFocusRequester() + + val rotaryHaptics = + if (columnState.hapticsEnabled) { + rememberRotaryHapticHandler(columnState.state) + } else { + rememberDisabledHaptic() + } + + val modifierWithRotary = + when (columnState.rotaryMode) { + RotaryMode.Snap -> + modifier.rotaryWithSnap( + focusRequester = focusRequester, + rotaryScrollAdapter = columnState.state.toRotaryScrollAdapter(), + reverseDirection = columnState.reverseLayout, + rotaryHaptics = rotaryHaptics, + ) + RotaryMode.Scroll -> + modifier.rotaryWithScroll( + focusRequester = focusRequester, + scrollableState = columnState.state, + reverseDirection = columnState.reverseLayout, + rotaryHaptics = rotaryHaptics, + ) + else -> modifier + } + + ScalingLazyColumn( + modifier = modifierWithRotary.fillMaxSize(), + state = columnState.state, + contentPadding = columnState.contentPadding, + reverseLayout = columnState.reverseLayout, + verticalArrangement = columnState.verticalArrangement, + horizontalAlignment = columnState.horizontalAlignment, + flingBehavior = columnState.flingBehavior ?: ScrollableDefaults.flingBehavior(), + userScrollEnabled = columnState.userScrollEnabled, + scalingParams = columnState.scalingParams, + anchorType = columnState.anchorType, + autoCentering = columnState.autoCentering, + content = content, + ) +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/Haptics.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/Haptics.kt new file mode 100644 index 000000000..817bf7efe --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/Haptics.kt @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput + +import android.os.Build +import android.view.View +import androidx.compose.foundation.gestures.ScrollableState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalView +import kotlin.math.abs +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.withContext + +// This file is a copy of Haptics.kt from Horologist (go/horologist), +// remove it once Wear Compose 1.4 is landed (b/325560444). + +private const val DEBUG = false + +/** Debug logging that can be enabled. */ +private inline fun debugLog(generateMsg: () -> String) { + if (DEBUG) { + println("RotaryHaptics: ${generateMsg()}") + } +} + +/** + * Throttling events within specified timeframe. Only first and last events will be received. For a + * flow emitting elements 1 to 30, with a 100ms delay between them: + * ``` + * val flow = flow { + * for (i in 1..30) { + * delay(100) + * emit(i) + * } + * } + * ``` + * + * With timeframe=1000 only those integers will be received: 1, 10, 20, 30 . + */ +internal fun <T> Flow<T>.throttleLatest(timeframe: Long): Flow<T> = flow { + conflate().collect { + emit(it) + delay(timeframe) + } +} + +/** Handles haptics for rotary usage */ +interface RotaryHapticHandler { + + /** Handles haptics when scroll is used */ + fun handleScrollHaptic(scrollDelta: Float) + + /** Handles haptics when scroll with snap is used */ + fun handleSnapHaptic(scrollDelta: Float) +} + +/** + * Default implementation of [RotaryHapticHandler]. It handles haptic feedback based on the + * [scrollableState], scrolled pixels and [hapticsThresholdPx]. Haptic is not fired in this class, + * instead it's sent to [hapticsChannel] where it'll performed later. + * + * @param scrollableState Haptic performed based on this state + * @param hapticsChannel Channel to which haptic events will be sent + * @param hapticsThresholdPx A scroll threshold after which haptic is produced. + */ +class DefaultRotaryHapticHandler( + private val scrollableState: ScrollableState, + private val hapticsChannel: Channel<RotaryHapticsType>, + private val hapticsThresholdPx: Long = 50, +) : RotaryHapticHandler { + + private var overscrollHapticTriggered = false + private var currScrollPosition = 0f + private var prevHapticsPosition = 0f + + override fun handleScrollHaptic(scrollDelta: Float) { + if ( + (scrollDelta > 0 && !scrollableState.canScrollForward) || + (scrollDelta < 0 && !scrollableState.canScrollBackward) + ) { + if (!overscrollHapticTriggered) { + trySendHaptic(RotaryHapticsType.ScrollLimit) + overscrollHapticTriggered = true + } + } else { + overscrollHapticTriggered = false + currScrollPosition += scrollDelta + val diff = abs(currScrollPosition - prevHapticsPosition) + + if (diff >= hapticsThresholdPx) { + trySendHaptic(RotaryHapticsType.ScrollTick) + prevHapticsPosition = currScrollPosition + } + } + } + + override fun handleSnapHaptic(scrollDelta: Float) { + if ( + (scrollDelta > 0 && !scrollableState.canScrollForward) || + (scrollDelta < 0 && !scrollableState.canScrollBackward) + ) { + if (!overscrollHapticTriggered) { + trySendHaptic(RotaryHapticsType.ScrollLimit) + overscrollHapticTriggered = true + } + } else { + overscrollHapticTriggered = false + trySendHaptic(RotaryHapticsType.ScrollItemFocus) + } + } + + private fun trySendHaptic(rotaryHapticsType: RotaryHapticsType) { + // Ok to ignore the ChannelResult because we default to capacity = 2 and DROP_OLDEST + @Suppress("UNUSED_VARIABLE") val unused = hapticsChannel.trySend(rotaryHapticsType) + } +} + +/** Interface for Rotary haptic feedback */ +interface RotaryHapticFeedback { + fun performHapticFeedback(type: RotaryHapticsType) +} + +/** Rotary haptic types */ +@JvmInline +value class RotaryHapticsType(private val type: Int) { + companion object { + /** + * A scroll ticking haptic. Similar to texture haptic - performed each time when a + * scrollable content is scrolled by a certain distance + */ + val ScrollTick: RotaryHapticsType = RotaryHapticsType(1) + + /** + * An item focus (snap) haptic. Performed when a scrollable content is snapped to a specific + * item. + */ + val ScrollItemFocus: RotaryHapticsType = RotaryHapticsType(2) + + /** + * A limit(overscroll) haptic. Performed when a list reaches the limit (start or end) and + * can't scroll further + */ + val ScrollLimit: RotaryHapticsType = RotaryHapticsType(3) + } +} + +/** Remember disabled haptics handler */ +@Composable +fun rememberDisabledHaptic(): RotaryHapticHandler = remember { + object : RotaryHapticHandler { + + override fun handleScrollHaptic(scrollDelta: Float) { + // Do nothing + } + + override fun handleSnapHaptic(scrollDelta: Float) { + // Do nothing + } + } +} + +/** + * Remember rotary haptic handler. + * + * @param scrollableState A scrollableState, used to determine whether the end of the scrollable was + * reached or not. + * @param throttleThresholdMs Throttling events within specified timeframe. Only first and last + * events will be received. Check [throttleLatest] for more info. + * @param hapticsThresholdPx A scroll threshold after which haptic is produced. + * @param hapticsChannel Channel to which haptic events will be sent + * @param rotaryHaptics Interface for Rotary haptic feedback which performs haptics + */ +@Composable +fun rememberRotaryHapticHandler( + scrollableState: ScrollableState, + throttleThresholdMs: Long = 30, + hapticsThresholdPx: Long = 50, + hapticsChannel: Channel<RotaryHapticsType> = rememberHapticChannel(), + rotaryHaptics: RotaryHapticFeedback = rememberDefaultRotaryHapticFeedback(), +): RotaryHapticHandler { + return remember(scrollableState, hapticsChannel, rotaryHaptics) { + DefaultRotaryHapticHandler(scrollableState, hapticsChannel, hapticsThresholdPx) + } + .apply { + LaunchedEffect(hapticsChannel) { + hapticsChannel.receiveAsFlow().throttleLatest(throttleThresholdMs).collect { + hapticType -> + // 'withContext' launches performHapticFeedback in a separate thread, + // as otherwise it produces a visible lag (b/219776664) + val currentTime = System.currentTimeMillis() + debugLog { "Haptics started" } + withContext(Dispatchers.Default) { + debugLog { + "Performing haptics, delay: " + + "${System.currentTimeMillis() - currentTime}" + } + rotaryHaptics.performHapticFeedback(hapticType) + } + } + } + } +} + +@Composable +private fun rememberHapticChannel() = remember { + Channel<RotaryHapticsType>( + capacity = 2, + onBufferOverflow = BufferOverflow.DROP_OLDEST, + ) +} + +@Composable +public fun rememberDefaultRotaryHapticFeedback(): RotaryHapticFeedback = + LocalView.current.let { view -> remember { findDeviceSpecificHapticFeedback(view) } } + +internal fun findDeviceSpecificHapticFeedback(view: View): RotaryHapticFeedback = + if (isSamsungWatch()) { + SamsungWatchHapticFeedback(view) + } else { + DefaultRotaryHapticFeedback(view) + } + +/** Default Rotary implementation for [RotaryHapticFeedback] */ +class DefaultRotaryHapticFeedback(private val view: View) : RotaryHapticFeedback { + + override fun performHapticFeedback( + type: RotaryHapticsType, + ) { + when (type) { + RotaryHapticsType.ScrollItemFocus -> { + view.performHapticFeedback(SCROLL_ITEM_FOCUS) + } + RotaryHapticsType.ScrollTick -> { + view.performHapticFeedback(SCROLL_TICK) + } + RotaryHapticsType.ScrollLimit -> { + view.performHapticFeedback(SCROLL_LIMIT) + } + } + } + + private companion object { + // Hidden constants from HapticFeedbackConstants + const val SCROLL_TICK: Int = 18 + const val SCROLL_ITEM_FOCUS: Int = 19 + const val SCROLL_LIMIT: Int = 20 + } +} + +/** Implementation of [RotaryHapticFeedback] for Samsung devices */ +private class SamsungWatchHapticFeedback(private val view: View) : RotaryHapticFeedback { + override fun performHapticFeedback( + type: RotaryHapticsType, + ) { + when (type) { + RotaryHapticsType.ScrollItemFocus -> { + view.performHapticFeedback(102) + } + RotaryHapticsType.ScrollTick -> { + view.performHapticFeedback(102) + } + RotaryHapticsType.ScrollLimit -> { + view.performHapticFeedback(50107) + } + } + } +} + +private fun isSamsungWatch(): Boolean = Build.MANUFACTURER.contains("Samsung", ignoreCase = true) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/Rotary.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/Rotary.kt new file mode 100644 index 000000000..19a6ea671 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/Rotary.kt @@ -0,0 +1,1232 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput + +import android.view.ViewConfiguration +import androidx.compose.animation.core.AnimationState +import androidx.compose.animation.core.CubicBezierEasing +import androidx.compose.animation.core.Easing +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.SpringSpec +import androidx.compose.animation.core.animateTo +import androidx.compose.animation.core.copy +import androidx.compose.animation.core.spring +import androidx.compose.animation.core.tween +import androidx.compose.foundation.MutatePriority +import androidx.compose.foundation.focusable +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.gestures.ScrollableDefaults +import androidx.compose.foundation.gestures.ScrollableState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.runtime.snapshots.Snapshot +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.input.rotary.RotaryInputModifierNode +import androidx.compose.ui.input.rotary.RotaryScrollEvent +import androidx.compose.ui.node.ModifierNodeElement +import androidx.compose.ui.platform.InspectorInfo +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.debugInspectorInfo +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.util.fastSumBy +import androidx.compose.ui.util.lerp +import androidx.wear.compose.foundation.ExperimentalWearFoundationApi +import androidx.wear.compose.foundation.lazy.ScalingLazyListState +import androidx.wear.compose.foundation.rememberActiveFocusRequester +import kotlin.math.abs +import kotlin.math.absoluteValue +import kotlin.math.sign +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.async +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.transformLatest +import kotlinx.coroutines.launch + +// This file is a copy of Rotary.kt from Horologist (go/horologist), +// remove it once Wear Compose 1.4 is landed (b/325560444). + +/** + * A modifier which connects rotary events with scrollable. This modifier supports scroll with + * fling. + * + * @param scrollableState Scrollable state which will be scrolled while receiving rotary events + * @param focusRequester Requests the focus for rotary input. By default comes from + * [rememberActiveFocusRequester], which is used with [HierarchicalFocusCoordinator] + * @param flingBehavior Logic describing fling behavior. If null fling will not happen. + * @param rotaryHaptics Class which will handle haptic feedback + * @param reverseDirection Reverse the direction of scrolling. Should be aligned with Scrollable + * `reverseDirection` parameter + */ +@OptIn(ExperimentalWearFoundationApi::class) +@Suppress("ComposableModifierFactory") +@Composable +fun Modifier.rotaryWithScroll( + scrollableState: ScrollableState, + focusRequester: FocusRequester = rememberActiveFocusRequester(), + flingBehavior: FlingBehavior? = ScrollableDefaults.flingBehavior(), + rotaryHaptics: RotaryHapticHandler = rememberRotaryHapticHandler(scrollableState), + reverseDirection: Boolean = false, +): Modifier = + rotaryHandler( + rotaryScrollHandler = + RotaryDefaults.rememberFlingHandler(scrollableState, flingBehavior), + reverseDirection = reverseDirection, + rotaryHaptics = rotaryHaptics, + inspectorInfo = + debugInspectorInfo { + name = "rotaryWithFling" + properties["scrollableState"] = scrollableState + properties["focusRequester"] = focusRequester + properties["flingBehavior"] = flingBehavior + properties["rotaryHaptics"] = rotaryHaptics + properties["reverseDirection"] = reverseDirection + }, + ) + .focusRequester(focusRequester) + .focusable() + +/** + * A modifier which connects rotary events with scrollable. This modifier supports snap. + * + * @param focusRequester Requests the focus for rotary input. By default comes from + * [rememberActiveFocusRequester], which is used with [HierarchicalFocusCoordinator] + * @param rotaryScrollAdapter A connection between scrollable objects and rotary events + * @param rotaryHaptics Class which will handle haptic feedback + * @param reverseDirection Reverse the direction of scrolling. Should be aligned with Scrollable + * `reverseDirection` parameter + */ +@OptIn(ExperimentalWearFoundationApi::class) +@Suppress("ComposableModifierFactory") +@Composable +fun Modifier.rotaryWithSnap( + rotaryScrollAdapter: RotaryScrollAdapter, + focusRequester: FocusRequester = rememberActiveFocusRequester(), + snapParameters: SnapParameters = RotaryDefaults.snapParametersDefault, + rotaryHaptics: RotaryHapticHandler = + rememberRotaryHapticHandler(rotaryScrollAdapter.scrollableState), + reverseDirection: Boolean = false, +): Modifier = + rotaryHandler( + rotaryScrollHandler = + RotaryDefaults.rememberSnapHandler(rotaryScrollAdapter, snapParameters), + reverseDirection = reverseDirection, + rotaryHaptics = rotaryHaptics, + inspectorInfo = + debugInspectorInfo { + name = "rotaryWithFling" + properties["rotaryScrollAdapter"] = rotaryScrollAdapter + properties["focusRequester"] = focusRequester + properties["snapParameters"] = snapParameters + properties["rotaryHaptics"] = rotaryHaptics + properties["reverseDirection"] = reverseDirection + }, + ) + .focusRequester(focusRequester) + .focusable() + +/** An extension function for creating [RotaryScrollAdapter] from [ScalingLazyListState] */ +@Composable +fun ScalingLazyListState.toRotaryScrollAdapter(): RotaryScrollAdapter = + remember(this) { ScalingLazyColumnRotaryScrollAdapter(this) } + +/** An implementation of rotary scroll adapter for [ScalingLazyColumn] */ +class ScalingLazyColumnRotaryScrollAdapter( + override val scrollableState: ScalingLazyListState, +) : RotaryScrollAdapter { + + /** Calculates an average height of an item by taking an average from visible items height. */ + override fun averageItemSize(): Float { + val visibleItems = scrollableState.layoutInfo.visibleItemsInfo + return (visibleItems.fastSumBy { it.unadjustedSize } / visibleItems.size).toFloat() + } + + /** Current (centred) item index */ + override fun currentItemIndex(): Int = scrollableState.centerItemIndex + + /** An offset from the item centre */ + override fun currentItemOffset(): Float = scrollableState.centerItemScrollOffset.toFloat() + + /** The total count of items in ScalingLazyColumn */ + override fun totalItemsCount(): Int = scrollableState.layoutInfo.totalItemsCount +} + +/** An adapter which connects scrollableState to Rotary */ +interface RotaryScrollAdapter { + + /** A scrollable state. Used for performing scroll when Rotary events received */ + val scrollableState: ScrollableState + + /** Average size of an item. Used for estimating the scrollable distance */ + fun averageItemSize(): Float + + /** A current item index. Used for scrolling */ + fun currentItemIndex(): Int + + /** An offset from the centre or the border of the current item. */ + fun currentItemOffset(): Float + + /** The total count of items in [scrollableState] */ + fun totalItemsCount(): Int +} + +/** Defaults for rotary modifiers */ +object RotaryDefaults { + + /** Returns default [SnapParameters] */ + val snapParametersDefault: SnapParameters = + SnapParameters( + snapOffset = 0, + thresholdDivider = 1.5f, + resistanceFactor = 3f, + ) + + /** Returns whether the input is Low-res (a bezel) or high-res(a crown/rsb). */ + @Composable + fun isLowResInput(): Boolean = + LocalContext.current.packageManager.hasSystemFeature( + "android.hardware.rotaryencoder.lowres" + ) + + /** + * Handles scroll with fling. + * + * @param scrollableState Scrollable state which will be scrolled while receiving rotary events + * @param flingBehavior Logic describing Fling behavior. If null - fling will not happen + * @param isLowRes Whether the input is Low-res (a bezel) or high-res(a crown/rsb) + */ + @Composable + internal fun rememberFlingHandler( + scrollableState: ScrollableState, + flingBehavior: FlingBehavior? = null, + isLowRes: Boolean = isLowResInput(), + ): RotaryScrollHandler { + val viewConfiguration = ViewConfiguration.get(LocalContext.current) + + return remember(scrollableState, flingBehavior, isLowRes) { + // Remove unnecessary recompositions by disabling tracking of changes inside of + // this block. This algorithm properly reads all updated values and + // don't need recomposition when those values change. + Snapshot.withoutReadObservation { + debugLog { "isLowRes : $isLowRes" } + fun rotaryFlingBehavior() = + flingBehavior?.run { + RotaryFlingBehavior( + scrollableState, + flingBehavior, + viewConfiguration, + flingTimeframe = + if (isLowRes) lowResFlingTimeframe else highResFlingTimeframe, + ) + } + + fun scrollBehavior() = RotaryScrollBehavior(scrollableState) + + if (isLowRes) { + LowResRotaryScrollHandler( + rotaryFlingBehaviorFactory = { rotaryFlingBehavior() }, + scrollBehaviorFactory = { scrollBehavior() }, + ) + } else { + HighResRotaryScrollHandler( + rotaryFlingBehaviorFactory = { rotaryFlingBehavior() }, + scrollBehaviorFactory = { scrollBehavior() }, + ) + } + } + } + } + + /** + * Handles scroll with snap + * + * @param rotaryScrollAdapter A connection between scrollable objects and rotary events + * @param snapParameters Snap parameters + */ + @Composable + internal fun rememberSnapHandler( + rotaryScrollAdapter: RotaryScrollAdapter, + snapParameters: SnapParameters = snapParametersDefault, + isLowRes: Boolean = isLowResInput(), + ): RotaryScrollHandler { + return remember(rotaryScrollAdapter, snapParameters) { + // Remove unnecessary recompositions by disabling tracking of changes inside of + // this block. This algorithm properly reads all updated values and + // don't need recomposition when those values change. + Snapshot.withoutReadObservation { + debugLog { "isLowRes : $isLowRes" } + if (isLowRes) { + LowResSnapHandler( + snapBehaviourFactory = { + RotarySnapBehavior(rotaryScrollAdapter, snapParameters) + }, + ) + } else { + HighResSnapHandler( + resistanceFactor = snapParameters.resistanceFactor, + thresholdBehaviorFactory = { + ThresholdBehavior( + rotaryScrollAdapter, + snapParameters.thresholdDivider, + ) + }, + snapBehaviourFactory = { + RotarySnapBehavior(rotaryScrollAdapter, snapParameters) + }, + scrollBehaviourFactory = { + RotaryScrollBehavior(rotaryScrollAdapter.scrollableState) + }, + ) + } + } + } + } + + private val lowResFlingTimeframe: Long = 100L + private val highResFlingTimeframe: Long = 30L +} + +/** + * Parameters used for snapping + * + * @param snapOffset an optional offset to be applied when snapping the item. After the snap the + * snapped items offset will be [snapOffset]. + */ +class SnapParameters( + val snapOffset: Int, + val thresholdDivider: Float, + val resistanceFactor: Float, +) { + /** Returns a snapping offset in [Dp] */ + @Composable + fun snapOffsetDp(): Dp { + return with(LocalDensity.current) { snapOffset.toDp() } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as SnapParameters + + if (snapOffset != other.snapOffset) return false + if (thresholdDivider != other.thresholdDivider) return false + if (resistanceFactor != other.resistanceFactor) return false + + return true + } + + override fun hashCode(): Int { + var result = snapOffset + result = 31 * result + thresholdDivider.hashCode() + result = 31 * result + resistanceFactor.hashCode() + return result + } +} + +/** An interface for handling scroll events */ +internal interface RotaryScrollHandler { + /** + * Handles scrolling events + * + * @param coroutineScope A scope for performing async actions + * @param event A scrollable event from rotary input, containing scrollable delta and timestamp + * @param rotaryHaptics + */ + suspend fun handleScrollEvent( + coroutineScope: CoroutineScope, + event: TimestampedDelta, + rotaryHaptics: RotaryHapticHandler, + ) +} + +/** + * Class responsible for Fling behaviour with rotary. It tracks and produces the fling when + * necessary + */ +internal class RotaryFlingBehavior( + private val scrollableState: ScrollableState, + private val flingBehavior: FlingBehavior, + viewConfiguration: ViewConfiguration, + private val flingTimeframe: Long, +) { + + // A time range during which the fling is valid. + // For simplicity it's twice as long as [flingTimeframe] + private val timeRangeToFling = flingTimeframe * 2 + + // A default fling factor for making fling slower + private val flingScaleFactor = 0.7f + + private var previousVelocity = 0f + + private val rotaryVelocityTracker = RotaryVelocityTracker() + + private val minFlingSpeed = viewConfiguration.scaledMinimumFlingVelocity.toFloat() + private val maxFlingSpeed = viewConfiguration.scaledMaximumFlingVelocity.toFloat() + private var latestEventTimestamp: Long = 0 + + private var flingVelocity: Float = 0f + private var flingTimestamp: Long = 0 + + /** Starts a new fling tracking session with specified timestamp */ + fun startFlingTracking(timestamp: Long) { + rotaryVelocityTracker.start(timestamp) + latestEventTimestamp = timestamp + previousVelocity = 0f + } + + /** Observing new event within a fling tracking session with new timestamp and delta */ + fun observeEvent(timestamp: Long, delta: Float) { + rotaryVelocityTracker.move(timestamp, delta) + latestEventTimestamp = timestamp + } + + /** Performing fling if necessary and calling [beforeFling] lambda before it is triggered */ + suspend fun trackFling(beforeFling: () -> Unit) { + val currentVelocity = rotaryVelocityTracker.velocity + debugLog { "currentVelocity: $currentVelocity" } + + if (abs(currentVelocity) >= abs(previousVelocity)) { + flingTimestamp = latestEventTimestamp + flingVelocity = currentVelocity * flingScaleFactor + } + previousVelocity = currentVelocity + + // Waiting for a fixed amount of time before checking the fling + delay(flingTimeframe) + + // For making a fling 2 criteria should be met: + // 1) no more than + // `rangeToFling` ms should pass between last fling detection + // and the time of last motion event + // 2) flingVelocity should exceed the minFlingSpeed + debugLog { + "Check fling: flingVelocity: $flingVelocity " + + "minFlingSpeed: $minFlingSpeed, maxFlingSpeed: $maxFlingSpeed" + } + if ( + latestEventTimestamp - flingTimestamp < timeRangeToFling && + abs(flingVelocity) > minFlingSpeed + ) { + // Stops scrollAnimationCoroutine because a fling will be performed + beforeFling() + val velocity = flingVelocity.coerceIn(-maxFlingSpeed, maxFlingSpeed) + scrollableState.scroll(MutatePriority.UserInput) { + with(flingBehavior) { + debugLog { "Flinging with velocity $velocity" } + performFling(velocity) + } + } + } + } +} + +/** + * A rotary event object which contains a [timestamp] of the rotary event and a scrolled [delta]. + */ +internal data class TimestampedDelta(val timestamp: Long, val delta: Float) + +/** + * This class does a smooth animation when the scroll by N pixels is done. This animation works well + * on Rsb(high-res) and Bezel(low-res) devices. + */ +internal class RotaryScrollBehavior( + private val scrollableState: ScrollableState, +) { + private var sequentialAnimation = false + private var scrollAnimation = AnimationState(0f) + private var prevPosition = 0f + + /** Handles scroll event to [targetValue] */ + suspend fun handleEvent(targetValue: Float) { + scrollableState.scroll(MutatePriority.UserInput) { + debugLog { "ScrollAnimation value before start: ${scrollAnimation.value}" } + + scrollAnimation.animateTo( + targetValue, + animationSpec = spring(), + sequentialAnimation = sequentialAnimation, + ) { + val delta = value - prevPosition + debugLog { "Animated by $delta, value: $value" } + scrollBy(delta) + prevPosition = value + sequentialAnimation = value != this.targetValue + } + } + } +} + +/** + * A helper class for snapping with rotary. Uses animateScrollToItem method for snapping to the Nth + * item. + */ +internal class RotarySnapBehavior( + private val rotaryScrollAdapter: RotaryScrollAdapter, + private val snapParameters: SnapParameters, +) { + private var snapTarget: Int = rotaryScrollAdapter.currentItemIndex() + private var sequentialSnap: Boolean = false + + private var anim = AnimationState(0f) + private var expectedDistance = 0f + + private val defaultStiffness = 200f + private var snapTargetUpdated = true + + /** + * Preparing snapping. This method should be called before [snapToTargetItem] is called. + * + * Snapping is done for current + [moveForElements] items. + * + * If [sequentialSnap] is true, items are summed up together. For example, if + * [prepareSnapForItems] is called with [moveForElements] = 2, 3, 5 -> then the snapping will + * happen to current + 10 items + * + * If [sequentialSnap] is false, then [moveForElements] are not summed up together. + */ + fun prepareSnapForItems(moveForElements: Int, sequentialSnap: Boolean) { + this.sequentialSnap = sequentialSnap + if (sequentialSnap) { + snapTarget += moveForElements + } else { + snapTarget = rotaryScrollAdapter.currentItemIndex() + moveForElements + } + snapTargetUpdated = true + snapTarget = snapTarget.coerceIn(0 until rotaryScrollAdapter.totalItemsCount()) + } + + /** Performs snapping to the closest item. */ + suspend fun snapToClosestItem() { + // Snapping to the closest item by using performFling method with 0 speed + rotaryScrollAdapter.scrollableState.scroll(MutatePriority.UserInput) { + debugLog { "snap to closest item" } + var prevPosition = 0f + AnimationState(0f).animateTo( + targetValue = -rotaryScrollAdapter.currentItemOffset(), + animationSpec = tween(durationMillis = 100, easing = FastOutSlowInEasing), + ) { + val animDelta = value - prevPosition + scrollBy(animDelta) + prevPosition = value + } + snapTarget = rotaryScrollAdapter.currentItemIndex() + } + } + + /** Returns true if top edge was reached */ + fun topEdgeReached(): Boolean = snapTarget <= 0 + + /** Returns true if bottom edge was reached */ + fun bottomEdgeReached(): Boolean = snapTarget >= rotaryScrollAdapter.totalItemsCount() - 1 + + /** Performs snapping to the specified in [prepareSnapForItems] element */ + suspend fun snapToTargetItem() { + if (sequentialSnap) { + anim = anim.copy(0f) + } else { + anim = AnimationState(0f) + } + rotaryScrollAdapter.scrollableState.scroll(MutatePriority.UserInput) { + // If snapTargetUpdated is true - then the target was updated so we + // need to do snap again + while (snapTargetUpdated) { + snapTargetUpdated = false + var latestCenterItem: Int + var continueFirstScroll = true + debugLog { "snapTarget $snapTarget" } + while (continueFirstScroll) { + latestCenterItem = rotaryScrollAdapter.currentItemIndex() + anim = anim.copy(0f) + expectedDistance = expectedDistanceTo(snapTarget, snapParameters.snapOffset) + debugLog { + "expectedDistance = $expectedDistance, " + + "scrollableState.centerItemScrollOffset " + + "${rotaryScrollAdapter.currentItemOffset()}" + } + continueFirstScroll = false + var prevPosition = 0f + + anim.animateTo( + expectedDistance, + animationSpec = + SpringSpec( + stiffness = defaultStiffness, + visibilityThreshold = 0.1f, + ), + sequentialAnimation = (anim.velocity != 0f), + ) { + val animDelta = value - prevPosition + debugLog { + "First animation, value:$value, velocity:$velocity, " + + "animDelta:$animDelta" + } + + // Exit animation if snap target was updated + if (snapTargetUpdated) cancelAnimation() + + scrollBy(animDelta) + prevPosition = value + + if (latestCenterItem != rotaryScrollAdapter.currentItemIndex()) { + continueFirstScroll = true + cancelAnimation() + return@animateTo + } + + debugLog { "centerItemIndex = ${rotaryScrollAdapter.currentItemIndex()}" } + if (rotaryScrollAdapter.currentItemIndex() == snapTarget) { + debugLog { "Target is visible. Cancelling first animation" } + debugLog { + "scrollableState.centerItemScrollOffset " + + "${rotaryScrollAdapter.currentItemOffset()}" + } + expectedDistance = -rotaryScrollAdapter.currentItemOffset() + continueFirstScroll = false + cancelAnimation() + return@animateTo + } + } + } + // Exit animation if snap target was updated + if (snapTargetUpdated) continue + + anim = anim.copy(0f) + var prevPosition = 0f + anim.animateTo( + expectedDistance, + animationSpec = + SpringSpec( + stiffness = defaultStiffness, + visibilityThreshold = 0.1f, + ), + sequentialAnimation = (anim.velocity != 0f), + ) { + // Exit animation if snap target was updated + if (snapTargetUpdated) cancelAnimation() + + val animDelta = value - prevPosition + debugLog { "Final animation. velocity:$velocity, animDelta:$animDelta" } + scrollBy(animDelta) + prevPosition = value + } + } + } + } + + private fun expectedDistanceTo(index: Int, targetScrollOffset: Int): Float { + val averageSize = rotaryScrollAdapter.averageItemSize() + val indexesDiff = index - rotaryScrollAdapter.currentItemIndex() + debugLog { "Average size $averageSize" } + return (averageSize * indexesDiff) + targetScrollOffset - + rotaryScrollAdapter.currentItemOffset() + } +} + +/** + * A modifier which handles rotary events. It accepts ScrollHandler as the input - a class where + * main logic about how scroll should be handled is lying + */ +internal fun Modifier.rotaryHandler( + rotaryScrollHandler: RotaryScrollHandler, + reverseDirection: Boolean, + rotaryHaptics: RotaryHapticHandler, + inspectorInfo: InspectorInfo.() -> Unit, +): Modifier = + this then + RotaryHandlerElement( + rotaryScrollHandler, + reverseDirection, + rotaryHaptics, + inspectorInfo, + ) + +/** + * Batching requests for scrolling events. This function combines all events together (except first) + * within specified timeframe. Should help with performance on high-res devices. + */ +@OptIn(ExperimentalCoroutinesApi::class) +internal fun Flow<TimestampedDelta>.batchRequestsWithinTimeframe( + timeframe: Long +): Flow<TimestampedDelta> { + var delta = 0f + var lastTimestamp = -timeframe + return if (timeframe == 0L) { + this + } else { + this.transformLatest { + delta += it.delta + debugLog { "Batching requests. delta:$delta" } + if (lastTimestamp + timeframe <= it.timestamp) { + lastTimestamp = it.timestamp + debugLog { "No events before, delta= $delta" } + emit(TimestampedDelta(it.timestamp, delta)) + } else { + delay(timeframe) + debugLog { "After delay, delta= $delta" } + if (delta > 0f) { + emit(TimestampedDelta(it.timestamp, delta)) + } + } + delta = 0f + } + } +} + +/** + * A scroll handler for RSB(high-res) without snapping and with or without fling A list is scrolled + * by the number of pixels received from the rotary device. + * + * This class is a little bit different from LowResScrollHandler class - it has a filtering for + * events which are coming with wrong sign ( this happens to rsb devices, especially at the end of + * the scroll) + * + * This scroll handler supports fling. It can be set with [RotaryFlingBehavior]. + */ +internal class HighResRotaryScrollHandler( + private val rotaryFlingBehaviorFactory: () -> RotaryFlingBehavior?, + private val scrollBehaviorFactory: () -> RotaryScrollBehavior, + private val hapticsThreshold: Long = 50, +) : RotaryScrollHandler { + + // This constant is specific for high-res devices. Because that input values + // can sometimes come with different sign, we have to filter them in this threshold + private val gestureThresholdTime = 200L + private var scrollJob: Job = CompletableDeferred<Unit>() + private var flingJob: Job = CompletableDeferred<Unit>() + + private var previousScrollEventTime = 0L + private var rotaryScrollDistance = 0f + + private var rotaryFlingBehavior: RotaryFlingBehavior? = rotaryFlingBehaviorFactory() + private var scrollBehavior: RotaryScrollBehavior = scrollBehaviorFactory() + + override suspend fun handleScrollEvent( + coroutineScope: CoroutineScope, + event: TimestampedDelta, + rotaryHaptics: RotaryHapticHandler, + ) { + val time = event.timestamp + val isOppositeScrollValue = isOppositeValueAfterScroll(event.delta) + + if (isNewScrollEvent(time)) { + debugLog { "New scroll event" } + resetTracking(time) + rotaryScrollDistance = event.delta + } else { + // Due to the physics of Rotary side button, some events might come + // with an opposite axis value - either at the start or at the end of the motion. + // We don't want to use these values for fling calculations. + if (!isOppositeScrollValue) { + rotaryFlingBehavior?.observeEvent(event.timestamp, event.delta) + } else { + debugLog { "Opposite value after scroll :${event.delta}" } + } + rotaryScrollDistance += event.delta + } + + scrollJob.cancel() + + rotaryHaptics.handleScrollHaptic(event.delta) + debugLog { "Rotary scroll distance: $rotaryScrollDistance" } + + previousScrollEventTime = time + scrollJob = coroutineScope.async { scrollBehavior.handleEvent(rotaryScrollDistance) } + + if (rotaryFlingBehavior != null) { + flingJob.cancel() + flingJob = + coroutineScope.async { + rotaryFlingBehavior?.trackFling( + beforeFling = { + debugLog { "Calling before fling section" } + scrollJob.cancel() + scrollBehavior = scrollBehaviorFactory() + } + ) + } + } + } + + private fun isOppositeValueAfterScroll(delta: Float): Boolean = + rotaryScrollDistance * delta < 0f && (abs(delta) < abs(rotaryScrollDistance)) + + private fun isNewScrollEvent(timestamp: Long): Boolean { + val timeDelta = timestamp - previousScrollEventTime + return previousScrollEventTime == 0L || timeDelta > gestureThresholdTime + } + + private fun resetTracking(timestamp: Long) { + scrollBehavior = scrollBehaviorFactory() + rotaryFlingBehavior = rotaryFlingBehaviorFactory() + rotaryFlingBehavior?.startFlingTracking(timestamp) + } +} + +/** + * A scroll handler for Bezel(low-res) without snapping. This scroll handler supports fling. It can + * be set with RotaryFlingBehavior. + */ +internal class LowResRotaryScrollHandler( + private val rotaryFlingBehaviorFactory: () -> RotaryFlingBehavior?, + private val scrollBehaviorFactory: () -> RotaryScrollBehavior, +) : RotaryScrollHandler { + + private val gestureThresholdTime = 200L + private var previousScrollEventTime = 0L + private var rotaryScrollDistance = 0f + + private var scrollJob: Job = CompletableDeferred<Unit>() + private var flingJob: Job = CompletableDeferred<Unit>() + + private var rotaryFlingBehavior: RotaryFlingBehavior? = rotaryFlingBehaviorFactory() + private var scrollBehavior: RotaryScrollBehavior = scrollBehaviorFactory() + + override suspend fun handleScrollEvent( + coroutineScope: CoroutineScope, + event: TimestampedDelta, + rotaryHaptics: RotaryHapticHandler, + ) { + val time = event.timestamp + + if (isNewScrollEvent(time)) { + resetTracking(time) + rotaryScrollDistance = event.delta + } else { + rotaryFlingBehavior?.observeEvent(event.timestamp, event.delta) + rotaryScrollDistance += event.delta + } + + scrollJob.cancel() + flingJob.cancel() + + rotaryHaptics.handleScrollHaptic(event.delta) + debugLog { "Rotary scroll distance: $rotaryScrollDistance" } + + previousScrollEventTime = time + scrollJob = coroutineScope.async { scrollBehavior.handleEvent(rotaryScrollDistance) } + + flingJob = + coroutineScope.async { + rotaryFlingBehavior?.trackFling( + beforeFling = { + debugLog { "Calling before fling section" } + scrollJob.cancel() + scrollBehavior = scrollBehaviorFactory() + }, + ) + } + } + + private fun isNewScrollEvent(timestamp: Long): Boolean { + val timeDelta = timestamp - previousScrollEventTime + return previousScrollEventTime == 0L || timeDelta > gestureThresholdTime + } + + private fun resetTracking(timestamp: Long) { + scrollBehavior = scrollBehaviorFactory() + debugLog { "Velocity tracker reset" } + rotaryFlingBehavior = rotaryFlingBehaviorFactory() + rotaryFlingBehavior?.startFlingTracking(timestamp) + } +} + +/** + * A scroll handler for RSB(high-res) with snapping and without fling Snapping happens after a + * threshold is reached ( set in [RotarySnapBehavior]) + * + * This scroll handler doesn't support fling. + */ +internal class HighResSnapHandler( + private val resistanceFactor: Float, + private val thresholdBehaviorFactory: () -> ThresholdBehavior, + private val snapBehaviourFactory: () -> RotarySnapBehavior, + private val scrollBehaviourFactory: () -> RotaryScrollBehavior, +) : RotaryScrollHandler { + private val gestureThresholdTime = 200L + private val snapDelay = 100L + private val maxSnapsPerEvent = 2 + + private var scrollJob: Job = CompletableDeferred<Unit>() + private var snapJob: Job = CompletableDeferred<Unit>() + + private var previousScrollEventTime = 0L + private var snapAccumulator = 0f + private var rotaryScrollDistance = 0f + private var scrollInProgress = false + + private var snapBehaviour = snapBehaviourFactory() + private var scrollBehaviour = scrollBehaviourFactory() + private var thresholdBehavior = thresholdBehaviorFactory() + + private val scrollEasing: Easing = CubicBezierEasing(0.0f, 0.0f, 0.5f, 1.0f) + + override suspend fun handleScrollEvent( + coroutineScope: CoroutineScope, + event: TimestampedDelta, + rotaryHaptics: RotaryHapticHandler, + ) { + val time = event.timestamp + + if (isNewScrollEvent(time)) { + debugLog { "New scroll event" } + resetTracking() + snapJob.cancel() + snapBehaviour = snapBehaviourFactory() + scrollBehaviour = scrollBehaviourFactory() + thresholdBehavior = thresholdBehaviorFactory() + thresholdBehavior.startThresholdTracking(time) + snapAccumulator = 0f + rotaryScrollDistance = 0f + } + + if (!isOppositeValueAfterScroll(event.delta)) { + thresholdBehavior.observeEvent(event.timestamp, event.delta) + } else { + debugLog { "Opposite value after scroll :${event.delta}" } + } + + thresholdBehavior.applySmoothing() + val snapThreshold = thresholdBehavior.snapThreshold() + + snapAccumulator += event.delta + if (!snapJob.isActive) { + val resistanceCoeff = + 1 - scrollEasing.transform(rotaryScrollDistance.absoluteValue / snapThreshold) + rotaryScrollDistance += event.delta * resistanceCoeff + } + + debugLog { "Snap accumulator: $snapAccumulator" } + debugLog { "Rotary scroll distance: $rotaryScrollDistance" } + + debugLog { "snapThreshold: $snapThreshold" } + previousScrollEventTime = time + + if (abs(snapAccumulator) > snapThreshold) { + scrollInProgress = false + scrollBehaviour = scrollBehaviourFactory() + scrollJob.cancel() + + val snapDistance = + (snapAccumulator / snapThreshold) + .toInt() + .coerceIn(-maxSnapsPerEvent..maxSnapsPerEvent) + snapAccumulator -= snapThreshold * snapDistance + val sequentialSnap = snapJob.isActive + + debugLog { + "Snap threshold reached: snapDistance:$snapDistance, " + + "sequentialSnap: $sequentialSnap, " + + "snap accumulator remaining: $snapAccumulator" + } + if ( + (!snapBehaviour.topEdgeReached() && snapDistance < 0) || + (!snapBehaviour.bottomEdgeReached() && snapDistance > 0) + ) { + rotaryHaptics.handleSnapHaptic(event.delta) + } + + snapBehaviour.prepareSnapForItems(snapDistance, sequentialSnap) + if (!snapJob.isActive) { + snapJob.cancel() + snapJob = + coroutineScope.async { + debugLog { "Snap started" } + try { + snapBehaviour.snapToTargetItem() + } finally { + debugLog { "Snap called finally" } + } + } + } + rotaryScrollDistance = 0f + } else { + if (!snapJob.isActive) { + scrollJob.cancel() + debugLog { "Scrolling for $rotaryScrollDistance/$resistanceFactor px" } + scrollJob = + coroutineScope.async { + scrollBehaviour.handleEvent(rotaryScrollDistance / resistanceFactor) + } + delay(snapDelay) + scrollInProgress = false + scrollBehaviour = scrollBehaviourFactory() + rotaryScrollDistance = 0f + snapAccumulator = 0f + snapBehaviour.prepareSnapForItems(0, false) + + snapJob.cancel() + snapJob = coroutineScope.async { snapBehaviour.snapToClosestItem() } + } + } + } + + private fun isOppositeValueAfterScroll(delta: Float): Boolean = + sign(rotaryScrollDistance) * sign(delta) == -1f && (abs(delta) < abs(rotaryScrollDistance)) + + private fun isNewScrollEvent(timestamp: Long): Boolean { + val timeDelta = timestamp - previousScrollEventTime + return previousScrollEventTime == 0L || timeDelta > gestureThresholdTime + } + + private fun resetTracking() { + scrollInProgress = true + } +} + +/** + * A scroll handler for RSB(high-res) with snapping and without fling Snapping happens after a + * threshold is reached ( set in [RotarySnapBehavior]) + * + * This scroll handler doesn't support fling. + */ +internal class LowResSnapHandler( + private val snapBehaviourFactory: () -> RotarySnapBehavior, +) : RotaryScrollHandler { + private val gestureThresholdTime = 200L + + private var snapJob: Job = CompletableDeferred<Unit>() + + private var previousScrollEventTime = 0L + private var snapAccumulator = 0f + private var scrollInProgress = false + + private var snapBehaviour = snapBehaviourFactory() + + override suspend fun handleScrollEvent( + coroutineScope: CoroutineScope, + event: TimestampedDelta, + rotaryHaptics: RotaryHapticHandler, + ) { + val time = event.timestamp + + if (isNewScrollEvent(time)) { + debugLog { "New scroll event" } + resetTracking() + snapJob.cancel() + snapBehaviour = snapBehaviourFactory() + snapAccumulator = 0f + } + + snapAccumulator += event.delta + + debugLog { "Snap accumulator: $snapAccumulator" } + + previousScrollEventTime = time + + if (abs(snapAccumulator) > 1f) { + scrollInProgress = false + + val snapDistance = sign(snapAccumulator).toInt() + rotaryHaptics.handleSnapHaptic(event.delta) + val sequentialSnap = snapJob.isActive + debugLog { + "Snap threshold reached: snapDistance:$snapDistance, " + + "sequentialSnap: $sequentialSnap, " + + "snap accumulator: $snapAccumulator" + } + + snapBehaviour.prepareSnapForItems(snapDistance, sequentialSnap) + if (!snapJob.isActive) { + snapJob.cancel() + snapJob = + coroutineScope.async { + debugLog { "Snap started" } + try { + snapBehaviour.snapToTargetItem() + } finally { + debugLog { "Snap called finally" } + } + } + } + snapAccumulator = 0f + } + } + + private fun isNewScrollEvent(timestamp: Long): Boolean { + val timeDelta = timestamp - previousScrollEventTime + return previousScrollEventTime == 0L || timeDelta > gestureThresholdTime + } + + private fun resetTracking() { + scrollInProgress = true + } +} + +internal class ThresholdBehavior( + private val rotaryScrollAdapter: RotaryScrollAdapter, + private val thresholdDivider: Float, + private val minVelocity: Float = 300f, + private val maxVelocity: Float = 3000f, + private val smoothingConstant: Float = 0.4f, +) { + private val thresholdDividerEasing: Easing = CubicBezierEasing(0.5f, 0.0f, 0.5f, 1.0f) + + private val rotaryVelocityTracker = RotaryVelocityTracker() + + private var smoothedVelocity = 0f + + fun startThresholdTracking(time: Long) { + rotaryVelocityTracker.start(time) + smoothedVelocity = 0f + } + + fun observeEvent(timestamp: Long, delta: Float) { + rotaryVelocityTracker.move(timestamp, delta) + } + + fun applySmoothing() { + if (rotaryVelocityTracker.velocity != 0.0f) { + // smooth the velocity + smoothedVelocity = + exponentialSmoothing( + currentVelocity = rotaryVelocityTracker.velocity.absoluteValue, + prevVelocity = smoothedVelocity, + smoothingConstant = smoothingConstant, + ) + } + debugLog { "rotaryVelocityTracker velocity: ${rotaryVelocityTracker.velocity}" } + debugLog { "SmoothedVelocity: $smoothedVelocity" } + } + + fun snapThreshold(): Float { + val thresholdDividerFraction = + thresholdDividerEasing.transform( + inverseLerp( + minVelocity, + maxVelocity, + smoothedVelocity, + ), + ) + return rotaryScrollAdapter.averageItemSize() / + lerp( + 1f, + thresholdDivider, + thresholdDividerFraction, + ) + } + + private fun exponentialSmoothing( + currentVelocity: Float, + prevVelocity: Float, + smoothingConstant: Float, + ): Float = smoothingConstant * currentVelocity + (1 - smoothingConstant) * prevVelocity +} + +private data class RotaryHandlerElement( + private val rotaryScrollHandler: RotaryScrollHandler, + private val reverseDirection: Boolean, + private val rotaryHaptics: RotaryHapticHandler, + private val inspectorInfo: InspectorInfo.() -> Unit, +) : ModifierNodeElement<RotaryInputNode>() { + override fun create(): RotaryInputNode = + RotaryInputNode( + rotaryScrollHandler, + reverseDirection, + rotaryHaptics, + ) + + override fun update(node: RotaryInputNode) { + debugLog { "Update launched!" } + node.rotaryScrollHandler = rotaryScrollHandler + node.reverseDirection = reverseDirection + node.rotaryHaptics = rotaryHaptics + } + + override fun InspectorInfo.inspectableProperties() { + inspectorInfo() + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as RotaryHandlerElement + + if (rotaryScrollHandler != other.rotaryScrollHandler) return false + if (reverseDirection != other.reverseDirection) return false + if (rotaryHaptics != other.rotaryHaptics) return false + if (inspectorInfo != other.inspectorInfo) return false + + return true + } + + override fun hashCode(): Int { + var result = rotaryScrollHandler.hashCode() + result = 31 * result + reverseDirection.hashCode() + result = 31 * result + rotaryHaptics.hashCode() + result = 31 * result + inspectorInfo.hashCode() + return result + } +} + +private class RotaryInputNode( + var rotaryScrollHandler: RotaryScrollHandler, + var reverseDirection: Boolean, + var rotaryHaptics: RotaryHapticHandler, +) : RotaryInputModifierNode, Modifier.Node() { + + val channel = Channel<TimestampedDelta>(capacity = Channel.CONFLATED) + val flow = channel.receiveAsFlow() + + override fun onAttach() { + coroutineScope.launch { + flow.collectLatest { + debugLog { + "Scroll event received: " + "delta:${it.delta}, timestamp:${it.timestamp}" + } + rotaryScrollHandler.handleScrollEvent(this, it, rotaryHaptics) + } + } + } + + override fun onRotaryScrollEvent(event: RotaryScrollEvent): Boolean = false + + override fun onPreRotaryScrollEvent(event: RotaryScrollEvent): Boolean { + debugLog { "onPreRotaryScrollEvent" } + channel.trySend( + TimestampedDelta( + event.uptimeMillis, + event.verticalScrollPixels * if (reverseDirection) -1f else 1f, + ), + ) + return true + } +} + +private fun inverseLerp(start: Float, stop: Float, value: Float): Float { + return ((value - start) / (stop - start)).coerceIn(0f, 1f) +} + +/** Debug logging that can be enabled. */ +private const val DEBUG = false + +private inline fun debugLog(generateMsg: () -> String) { + if (DEBUG) { + println("RotaryScroll: ${generateMsg()}") + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/RotaryVelocityTracker.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/RotaryVelocityTracker.kt new file mode 100644 index 000000000..1719ecef3 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/rotaryinput/RotaryVelocityTracker.kt @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.wear.elements.rotaryinput + +import androidx.compose.ui.input.pointer.util.VelocityTracker1D + +// This file is a copy of RotaryVelocityTracker.kt from Horologist (go/horologist), +// remove it once Wear Compose 1.4 is landed (b/325560444). + +/** A wrapper around VelocityTracker1D to provide support for rotary input. */ +class RotaryVelocityTracker { + private var velocityTracker: VelocityTracker1D = VelocityTracker1D(true) + + /** Retrieve the last computed velocity. */ + val velocity: Float + get() = velocityTracker.calculateVelocity() + + /** Start tracking motion. */ + fun start(currentTime: Long) { + velocityTracker.resetTracking() + velocityTracker.addDataPoint(currentTime, 0f) + } + + /** Continue tracking motion as the input rotates. */ + fun move(currentTime: Long, delta: Float) { + velocityTracker.addDataPoint(currentTime, delta) + } + + /** Stop tracking motion. */ + fun end() { + velocityTracker.resetTracking() + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/model/WearPermissionUsageViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/model/WearPermissionUsageViewModel.kt new file mode 100644 index 000000000..c0e7e989c --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/model/WearPermissionUsageViewModel.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.ui.wear.model + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.android.permissioncontroller.permission.ui.viewmodel.BasePermissionUsageViewModel +import com.android.permissioncontroller.permission.ui.viewmodel.PermissionUsagesUiState + +class WearPermissionUsageViewModel( + permissionUsagesUiState: PermissionUsagesUiState?, + showSystemApps: Boolean, + show7DaysData: Boolean +) : ViewModel() { + val permissionUsagesUiStateLiveData = MutableLiveData(permissionUsagesUiState) + /** A livedata which stores [BasePermissionUsageViewModel.getShowSystemApps()]. */ + val showSystemAppsLiveData = MutableLiveData(showSystemApps) + + /** A livedata which stores [BasePermissionUsageViewModel.getShow7DaysData()]. */ + val show7DaysLiveData = MutableLiveData(show7DaysData) + + fun updatePermissionUsagesUiStateLiveData(newUiData: PermissionUsagesUiState?) { + permissionUsagesUiStateLiveData.value = newUiData + } +} + +/** Factory for a WearPermissionsUsageViewModel */ +class WearPermissionUsageViewModelFactory(val viewModel: BasePermissionUsageViewModel) : + ViewModelProvider.Factory { + override fun <T : ViewModel> create(modelClass: Class<T>): T { + @Suppress("UNCHECKED_CAST") + return WearPermissionUsageViewModel( + viewModel.getPermissionUsagesUiLiveData().value, + viewModel.getShowSystemApps(), + viewModel.getShow7DaysData() + ) + as T + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/model/WearUnusedAppsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/model/WearUnusedAppsViewModel.kt index 38810ddd6..a2d987e02 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/model/WearUnusedAppsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/model/WearUnusedAppsViewModel.kt @@ -34,7 +34,7 @@ class WearUnusedAppsViewModel : ViewModel() { /** A livedata which stores a map of unused apps group by UnusedPeriod. */ val unusedAppChipsLiveData = - MutableLiveData<MutableMap<UnusedPeriod, MutableMap<String, UnusedAppChip>>>() + MutableLiveData<Map<UnusedPeriod, Map<String, UnusedAppChip>>>() data class UnusedAppChip( val label: String, diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/WearPermissionTheme.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/WearPermissionTheme.kt new file mode 100644 index 000000000..dae4437b2 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/WearPermissionTheme.kt @@ -0,0 +1,131 @@ +package com.android.permissioncontroller.permission.ui.wear.theme + +import android.content.Context +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.annotation.StringRes +import androidx.annotation.VisibleForTesting +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.DeviceFontFamilyName +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.wear.compose.material.Colors +import androidx.wear.compose.material.MaterialTheme +import androidx.wear.compose.material.Typography +import com.android.permissioncontroller.R + +/** The Material 3 Theme Wrapper for Supporting RRO. */ +@Composable +fun WearPermissionTheme(content: @Composable () -> Unit) { + val context = LocalContext.current + val colors = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + overlayColors(context) + .copy(error = MaterialTheme.colors.error, onError = MaterialTheme.colors.onError) + } else { + MaterialTheme.colors + } + MaterialTheme(colors = colors, typography = deviceDefaultTypography(context), content = content) +} + +/** + * Creates a dynamic color maps that can be overlaid. 100 - Lightest shade; 0 - Darkest Shade; In + * wear we only support dark theme for the time being. Thus the fill colors and variants are dark + * and anything on top is light. We will use this custom redirection until wear compose material + * supports color scheming. + * + * The mapping is best case match on wear material color tokens from + * /android/clockwork/common/wearable/wearmaterial/color/res/values/color-tokens.xml + * + * @param context The context required to get system resource data. + */ +@RequiresApi(Build.VERSION_CODES.S) +@VisibleForTesting +internal fun overlayColors(context: Context): Colors { + val tonalPalette = dynamicTonalPalette(context) + return Colors( + background = Color.Black, + onBackground = Color.White, + primary = tonalPalette.primary90, + primaryVariant = tonalPalette.primary80, + onPrimary = tonalPalette.primary10, + secondary = tonalPalette.tertiary90, + secondaryVariant = tonalPalette.tertiary60, + onSecondary = tonalPalette.tertiary10, + surface = tonalPalette.neutral20, + onSurface = tonalPalette.neutral95, + onSurfaceVariant = tonalPalette.neutralVariant80, + ) +} + +private fun fontFamily(context: Context, @StringRes id: Int): FontFamily { + val typefaceName = context.resources.getString(id) + val font = Font(familyName = DeviceFontFamilyName(typefaceName)) + return FontFamily(font) +} + +/* + Only customizes font family. The material 3 roles to 2.5 are mapped to the best case matching of + google3/java/com/google/android/wearable/libraries/compose/theme/GoogleMaterialTheme.kt +*/ +internal fun deviceDefaultTypography(context: Context): Typography { + val defaultTypography = Typography() + return Typography( + display1 = + defaultTypography.display1.copy( + fontFamily = + fontFamily(context, R.string.wear_material_compose_display_1_font_family) + ), + display2 = + defaultTypography.display2.copy( + fontFamily = + fontFamily(context, R.string.wear_material_compose_display_2_font_family) + ), + display3 = + defaultTypography.display1.copy( + fontFamily = + fontFamily(context, R.string.wear_material_compose_display_3_font_family) + ), + title1 = + defaultTypography.title1.copy( + fontFamily = fontFamily(context, R.string.wear_material_compose_title_1_font_family) + ), + title2 = + defaultTypography.title2.copy( + fontFamily = fontFamily(context, R.string.wear_material_compose_title_2_font_family) + ), + title3 = + defaultTypography.title3.copy( + fontFamily = fontFamily(context, R.string.wear_material_compose_title_3_font_family) + ), + body1 = + defaultTypography.body1.copy( + fontFamily = fontFamily(context, R.string.wear_material_compose_body_1_font_family) + ), + body2 = + defaultTypography.body2.copy( + fontFamily = fontFamily(context, R.string.wear_material_compose_body_2_font_family) + ), + button = + defaultTypography.button.copy( + fontFamily = fontFamily(context, R.string.wear_material_compose_button_font_family) + ), + caption1 = + defaultTypography.caption1.copy( + fontFamily = + fontFamily(context, R.string.wear_material_compose_caption_1_font_family) + ), + caption2 = + defaultTypography.caption2.copy( + fontFamily = + fontFamily(context, R.string.wear_material_compose_caption_2_font_family) + ), + caption3 = + defaultTypography.caption3.copy( + fontFamily = + fontFamily(context, R.string.wear_material_compose_caption_3_font_family) + ), + ) +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/WearPermissionTonalPalette.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/WearPermissionTonalPalette.kt new file mode 100644 index 000000000..a86af8b3d --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/WearPermissionTonalPalette.kt @@ -0,0 +1,191 @@ +@file:Suppress("unused") + +package com.android.permissioncontroller.permission.ui.wear.theme + +import android.R +import android.content.Context +import android.os.Build +import androidx.annotation.ColorRes +import androidx.annotation.DoNotInline +import androidx.annotation.RequiresApi +import androidx.compose.ui.graphics.Color + +/** + * Tonal Palette structure in Material. + * + * A tonal palette is comprised of 5 tonal ranges. Each tonal range includes the 13 stops, or tonal + * swatches. + * + * Tonal range names are: + * - Neutral (N) + * - Neutral variant (NV) + * - Primary (P) + * - Secondary (S) + * - Tertiary (T) + */ +internal class WearPermissionTonalPalette( + // The neutral tonal range. + val neutral100: Color, + val neutral99: Color, + val neutral95: Color, + val neutral90: Color, + val neutral80: Color, + val neutral70: Color, + val neutral60: Color, + val neutral50: Color, + val neutral40: Color, + val neutral30: Color, + val neutral20: Color, + val neutral10: Color, + val neutral0: Color, + + // The neutral variant tonal range, sometimes called "neutral 2" + val neutralVariant100: Color, + val neutralVariant99: Color, + val neutralVariant95: Color, + val neutralVariant90: Color, + val neutralVariant80: Color, + val neutralVariant70: Color, + val neutralVariant60: Color, + val neutralVariant50: Color, + val neutralVariant40: Color, + val neutralVariant30: Color, + val neutralVariant20: Color, + val neutralVariant10: Color, + val neutralVariant0: Color, + + // The primary tonal range, also known as accent 1 + val primary100: Color, + val primary99: Color, + val primary95: Color, + val primary90: Color, + val primary80: Color, + val primary70: Color, + val primary60: Color, + val primary50: Color, + val primary40: Color, + val primary30: Color, + val primary20: Color, + val primary10: Color, + val primary0: Color, + + // The Secondary tonal range, also know as accent 2 + val secondary100: Color, + val secondary99: Color, + val secondary95: Color, + val secondary90: Color, + val secondary80: Color, + val secondary70: Color, + val secondary60: Color, + val secondary50: Color, + val secondary40: Color, + val secondary30: Color, + val secondary20: Color, + val secondary10: Color, + val secondary0: Color, + + // The tertiary tonal range, also known as accent 3 + val tertiary100: Color, + val tertiary99: Color, + val tertiary95: Color, + val tertiary90: Color, + val tertiary80: Color, + val tertiary70: Color, + val tertiary60: Color, + val tertiary50: Color, + val tertiary40: Color, + val tertiary30: Color, + val tertiary20: Color, + val tertiary10: Color, + val tertiary0: Color, +) +/** Dynamic colors for wear compose material to support resource overlay. */ +@RequiresApi(Build.VERSION_CODES.S) +// TODO: once we have proper support for this on Wear 6+, we will do something similar to +// https://source.corp.google.com/h/android/platform/superproject/+/androidx-main:frameworks/support/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/DynamicTonalPalette.android.kt;l=307-362?q=dynamicTonalPalette&sq=repo:android%2Fplatform%2Fsuperproject%20b:androidx-main +// Tracking Bug: b/270720571 +internal fun dynamicTonalPalette(context: Context) = + WearPermissionTonalPalette( + // The neutral tonal range from the generated dynamic color palette. + neutral100 = ColorResourceHelper.getColor(context, R.color.system_neutral1_0), + neutral99 = ColorResourceHelper.getColor(context, R.color.system_neutral1_10), + neutral95 = ColorResourceHelper.getColor(context, R.color.system_neutral1_50), + neutral90 = ColorResourceHelper.getColor(context, R.color.system_neutral1_100), + neutral80 = ColorResourceHelper.getColor(context, R.color.system_neutral1_200), + neutral70 = ColorResourceHelper.getColor(context, R.color.system_neutral1_300), + neutral60 = ColorResourceHelper.getColor(context, R.color.system_neutral1_400), + neutral50 = ColorResourceHelper.getColor(context, R.color.system_neutral1_500), + neutral40 = ColorResourceHelper.getColor(context, R.color.system_neutral1_600), + neutral30 = ColorResourceHelper.getColor(context, R.color.system_neutral1_700), + neutral20 = ColorResourceHelper.getColor(context, R.color.system_neutral1_800), + neutral10 = ColorResourceHelper.getColor(context, R.color.system_neutral1_900), + neutral0 = ColorResourceHelper.getColor(context, R.color.system_neutral1_1000), + + // The neutral variant tonal range, sometimes called "neutral 2", from the + // generated dynamic color palette. + neutralVariant100 = ColorResourceHelper.getColor(context, R.color.system_neutral2_0), + neutralVariant99 = ColorResourceHelper.getColor(context, R.color.system_neutral2_10), + neutralVariant95 = ColorResourceHelper.getColor(context, R.color.system_neutral2_50), + neutralVariant90 = ColorResourceHelper.getColor(context, R.color.system_neutral2_100), + neutralVariant80 = ColorResourceHelper.getColor(context, R.color.system_neutral2_200), + neutralVariant70 = ColorResourceHelper.getColor(context, R.color.system_neutral2_300), + neutralVariant60 = ColorResourceHelper.getColor(context, R.color.system_neutral2_400), + neutralVariant50 = ColorResourceHelper.getColor(context, R.color.system_neutral2_500), + neutralVariant40 = ColorResourceHelper.getColor(context, R.color.system_neutral2_600), + neutralVariant30 = ColorResourceHelper.getColor(context, R.color.system_neutral2_700), + neutralVariant20 = ColorResourceHelper.getColor(context, R.color.system_neutral2_800), + neutralVariant10 = ColorResourceHelper.getColor(context, R.color.system_neutral2_900), + neutralVariant0 = ColorResourceHelper.getColor(context, R.color.system_neutral2_1000), + + // The primary tonal range from the generated dynamic color palette. + primary100 = ColorResourceHelper.getColor(context, R.color.system_accent1_0), + primary99 = ColorResourceHelper.getColor(context, R.color.system_accent1_10), + primary95 = ColorResourceHelper.getColor(context, R.color.system_accent1_50), + primary90 = ColorResourceHelper.getColor(context, R.color.system_accent1_100), + primary80 = ColorResourceHelper.getColor(context, R.color.system_accent1_200), + primary70 = ColorResourceHelper.getColor(context, R.color.system_accent1_300), + primary60 = ColorResourceHelper.getColor(context, R.color.system_accent1_400), + primary50 = ColorResourceHelper.getColor(context, R.color.system_accent1_500), + primary40 = ColorResourceHelper.getColor(context, R.color.system_accent1_600), + primary30 = ColorResourceHelper.getColor(context, R.color.system_accent1_700), + primary20 = ColorResourceHelper.getColor(context, R.color.system_accent1_800), + primary10 = ColorResourceHelper.getColor(context, R.color.system_accent1_900), + primary0 = ColorResourceHelper.getColor(context, R.color.system_accent1_1000), + + // The secondary tonal range from the generated dynamic color palette. + secondary100 = ColorResourceHelper.getColor(context, R.color.system_accent2_0), + secondary99 = ColorResourceHelper.getColor(context, R.color.system_accent2_10), + secondary95 = ColorResourceHelper.getColor(context, R.color.system_accent2_50), + secondary90 = ColorResourceHelper.getColor(context, R.color.system_accent2_100), + secondary80 = ColorResourceHelper.getColor(context, R.color.system_accent2_200), + secondary70 = ColorResourceHelper.getColor(context, R.color.system_accent2_300), + secondary60 = ColorResourceHelper.getColor(context, R.color.system_accent2_400), + secondary50 = ColorResourceHelper.getColor(context, R.color.system_accent2_500), + secondary40 = ColorResourceHelper.getColor(context, R.color.system_accent2_600), + secondary30 = ColorResourceHelper.getColor(context, R.color.system_accent2_700), + secondary20 = ColorResourceHelper.getColor(context, R.color.system_accent2_800), + secondary10 = ColorResourceHelper.getColor(context, R.color.system_accent2_900), + secondary0 = ColorResourceHelper.getColor(context, R.color.system_accent2_1000), + + // The tertiary tonal range from the generated dynamic color palette. + tertiary100 = ColorResourceHelper.getColor(context, R.color.system_accent3_0), + tertiary99 = ColorResourceHelper.getColor(context, R.color.system_accent3_10), + tertiary95 = ColorResourceHelper.getColor(context, R.color.system_accent3_50), + tertiary90 = ColorResourceHelper.getColor(context, R.color.system_accent3_100), + tertiary80 = ColorResourceHelper.getColor(context, R.color.system_accent3_200), + tertiary70 = ColorResourceHelper.getColor(context, R.color.system_accent3_300), + tertiary60 = ColorResourceHelper.getColor(context, R.color.system_accent3_400), + tertiary50 = ColorResourceHelper.getColor(context, R.color.system_accent3_500), + tertiary40 = ColorResourceHelper.getColor(context, R.color.system_accent3_600), + tertiary30 = ColorResourceHelper.getColor(context, R.color.system_accent3_700), + tertiary20 = ColorResourceHelper.getColor(context, R.color.system_accent3_800), + tertiary10 = ColorResourceHelper.getColor(context, R.color.system_accent3_900), + tertiary0 = ColorResourceHelper.getColor(context, R.color.system_accent3_1000), + ) + +private object ColorResourceHelper { + @DoNotInline + fun getColor(context: Context, @ColorRes id: Int): Color { + return Color(context.resources.getColor(id, context.theme)) + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/MultiDeviceUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/MultiDeviceUtils.kt deleted file mode 100644 index 2719b9766..000000000 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/MultiDeviceUtils.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.android.permissioncontroller.permission.utils - -import android.Manifest -import android.companion.virtual.VirtualDeviceManager -import android.content.Context -import android.os.Build -import android.provider.Settings -import androidx.annotation.ChecksSdkIntAtLeast -import com.android.modules.utils.build.SdkLevel -import com.android.permission.flags.Flags - -object MultiDeviceUtils { - const val DEFAULT_REMOTE_DEVICE_NAME = "remote device" - - /** - * Defines what runtime permissions are device aware. This can be replaced with an API from VDM - * which can take device's capabilities into account - */ - // TODO: b/298661870 - Use new API to get the list of device aware permissions - private val DEVICE_AWARE_PERMISSIONS: Set<String> = - setOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) - - @JvmStatic - fun isPermissionDeviceAware(permission: String): Boolean = - permission in DEVICE_AWARE_PERMISSIONS - - @JvmStatic - @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) - fun isDeviceAwareGrantFlowEnabled(): Boolean { - return SdkLevel.isAtLeastV() && Flags.deviceAwarePermissionGrant() - } - - @JvmStatic - fun getDeviceName(context: Context, deviceId: Int): String? { - // Pre Android V no permission requests can affect the VirtualDevice, thus return local - // device name. - if (!SdkLevel.isAtLeastV() || deviceId == ContextCompat.DEVICE_ID_DEFAULT) { - return Settings.Global.getString(context.contentResolver, Settings.Global.DEVICE_NAME) - } - val vdm: VirtualDeviceManager? = context.getSystemService(VirtualDeviceManager::class.java) - if (vdm != null) { - val virtualDevice = vdm.getVirtualDevice(deviceId) - if (virtualDevice != null) { - return if (virtualDevice.displayName != null) virtualDevice.displayName.toString() - else DEFAULT_REMOTE_DEVICE_NAME - } - } - throw IllegalArgumentException("No device name for device: $deviceId") - } -} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt index 840a033c3..f97acb130 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt @@ -33,7 +33,7 @@ import com.android.permissioncontroller.permission.model.livedatatypes.LightAppP */ object PermissionMapping { - private val LOG_TAG = "PermissionMapping" + private const val LOG_TAG = "PermissionMapping" private val PERMISSION_GROUPS_TO_DATA_CATEGORIES: Map<String, List<String>> = mapOf(Manifest.permission_group.LOCATION to listOf(DataCategoryConstants.CATEGORY_LOCATION)) @@ -375,7 +375,12 @@ object PermissionMapping { return Manifest.permission_group.CAMERA } - return AppOpsManager.opToPermission(opName)?.let { getGroupOfPlatformPermission(it) } + return try { + AppOpsManager.opToPermission(opName)?.let { getGroupOfPlatformPermission(it) } + } catch (e: IllegalArgumentException) { + Log.wtf(LOG_TAG, "No permission group found for $opName") + null + } } /** diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java index ad384cca7..8d53d7eca 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java @@ -54,6 +54,7 @@ import android.Manifest; import android.app.AppOpsManager; import android.app.Application; import android.app.admin.DevicePolicyManager; +import android.app.ecm.EnhancedConfirmationManager; import android.app.role.RoleManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; @@ -68,6 +69,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; +import android.content.pm.UserProperties; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.Bitmap; @@ -80,6 +82,7 @@ import android.os.Build; import android.os.Parcelable; import android.os.UserHandle; import android.os.UserManager; +import android.permission.flags.Flags; import android.provider.DeviceConfig; import android.provider.Settings; import android.text.Html; @@ -392,6 +395,8 @@ public final class Utils { /* do nothing - hide constructor */ } + private static Object sLock = new Object(); + private static ArrayMap<UserHandle, Context> sUserContexts = new ArrayMap<>(); /** @@ -406,11 +411,13 @@ public final class Utils { * @throws RuntimeException If the app has no package name attached, which should never happen */ public static @NonNull Context getUserContext(Context context, UserHandle user) { - if (!sUserContexts.containsKey(user)) { - sUserContexts.put(user, context.getApplicationContext() - .createContextAsUser(user, 0)); + synchronized (sLock) { + if (!sUserContexts.containsKey(user)) { + sUserContexts.put(user, context.getApplicationContext() + .createContextAsUser(user, 0)); + } + return Preconditions.checkNotNull(sUserContexts.get(user)); } - return Preconditions.checkNotNull(sUserContexts.get(user)); } /** @@ -1587,4 +1594,67 @@ public final class Utils { @NonNull ApplicationInfo applicationInfo) { return context.getPackageManager().getApplicationLabel(applicationInfo).toString(); } + + /** + * Returns whether the given user should be shown in the Settings UI in SdkLevel V+. This method + * will always return true for SdkLevels below V. + * + * @param userHandle The user for which to check whether it should be shown or not. + * @return true if it should be shown, false otherwise. + */ + public static boolean shouldShowInSettings(UserHandle userHandle, UserManager userManager) { + return !SdkLevel.isAtLeastV() || shouldShowInSettingsInternal(userHandle, userManager); + } + + /** + * Returns whether the given user should be shown in the Settings UI. + * + * @param userHandle The user for which to check whether it should be shown or not. + * @return true if it should be shown, false otherwise. + */ + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM) + private static boolean shouldShowInSettingsInternal( + UserHandle userHandle, UserManager userManager) { + var userProperties = userManager.getUserProperties(userHandle); + return !userManager.isQuietModeEnabled(userHandle) + || userProperties.getShowInQuietMode() != UserProperties.SHOW_IN_QUIET_MODE_HIDDEN; + } + + /** + * Check whether an application is restricted for this setting identifier and return the + * {@code Intent} for the restriction if it is. + * + * @param user the user to check for + * @param context the {@code Context} to retrieve system services + * + * @return the {@code Intent} for the restriction if the application is restricted for this + * setting identifier, or {@code null} otherwise. + */ + @Nullable + public static Intent getApplicationEnhancedConfirmationRestrictedIntentAsUser( + @NonNull UserHandle user, + @NonNull Context context, + @Nullable String packageName, + @Nullable String settingIdentifier) { + if (SdkLevel.isAtLeastV() && Flags.enhancedConfirmationModeApisEnabled()) { + Context userContext = Utils.getUserContext(context, user); + EnhancedConfirmationManager userEnhancedConfirmationManager = + userContext.getSystemService(EnhancedConfirmationManager.class); + if (packageName == null || settingIdentifier == null) return null; + try { + boolean isRestricted = userEnhancedConfirmationManager.isRestricted(packageName, + settingIdentifier); + if (isRestricted) { + return userEnhancedConfirmationManager.createRestrictedSettingDialogIntent( + packageName, settingIdentifier); + } + + } catch (PackageManager.NameNotFoundException e) { + Log.w(LOG_TAG, "Cannot check enhanced confirmation restriction for package: " + + packageName, e); + } + } + return null; + } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/v35/MultiDeviceUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/v35/MultiDeviceUtils.kt new file mode 100644 index 000000000..68b6f72a5 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/v35/MultiDeviceUtils.kt @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.utils.v35 + +import android.Manifest +import android.app.Application +import android.companion.virtual.VirtualDeviceManager +import android.content.Context +import android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME +import android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED +import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED +import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED +import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET +import android.os.Build +import android.permission.PermissionManager +import android.provider.Settings +import androidx.annotation.ChecksSdkIntAtLeast +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.DeviceUtils +import com.android.permissioncontroller.permission.utils.ContextCompat + +object MultiDeviceUtils { + const val DEFAULT_REMOTE_DEVICE_NAME = "remote device" + + /** + * Defines what runtime permissions are device aware. This can be replaced with an API from VDM + * which can take device's capabilities into account + */ + // TODO: b/298661870 - Use new API to get the list of device aware permissions + private val DEVICE_AWARE_PERMISSIONS: Set<String> = + setOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) + + private const val DEVICE_AWARE_PERMISSION_FLAG_MASK = + FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED or + FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED or + FLAG_PERMISSION_ONE_TIME or + FLAG_PERMISSION_USER_SET or + FLAG_PERMISSION_USER_FIXED + + @JvmStatic + fun isDeviceAwarePermissionSupported(context: Context): Boolean = + SdkLevel.isAtLeastV() && + !(DeviceUtils.isTelevision(context) || + DeviceUtils.isAuto(context) || + DeviceUtils.isWear(context)) + + @JvmStatic + fun isPermissionDeviceAware(permission: String): Boolean = + permission in DEVICE_AWARE_PERMISSIONS + + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + fun isPermissionDeviceAware(context: Context, deviceId: Int, permission: String): Boolean { + if (!SdkLevel.isAtLeastV()) { + return false + } + + if (permission !in DEVICE_AWARE_PERMISSIONS) { + return false + } + + val virtualDevice = + context.getSystemService(VirtualDeviceManager::class.java)!!.getVirtualDevice(deviceId) + ?: return false + + return when (permission) { + Manifest.permission.CAMERA -> virtualDevice.hasCustomCameraSupport() + Manifest.permission.RECORD_AUDIO -> virtualDevice.hasCustomAudioInputSupport() + else -> false + } + } + + @JvmStatic + fun getDeviceName(context: Context, deviceId: Int): String? { + // Pre Android V no permission requests can affect the VirtualDevice, thus return local + // device name. + if (!SdkLevel.isAtLeastV() || deviceId == ContextCompat.DEVICE_ID_DEFAULT) { + return Settings.Global.getString(context.contentResolver, Settings.Global.DEVICE_NAME) + } + val vdm: VirtualDeviceManager? = context.getSystemService(VirtualDeviceManager::class.java) + if (vdm != null) { + val virtualDevice = vdm.getVirtualDevice(deviceId) + if (virtualDevice != null) { + return if (virtualDevice.displayName != null) virtualDevice.displayName.toString() + else DEFAULT_REMOTE_DEVICE_NAME + } + } + throw IllegalArgumentException("No device name for device: $deviceId") + } + + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + fun isDefaultDeviceId(persistentDeviceId: String?) = + !SdkLevel.isAtLeastV() || + persistentDeviceId.isNullOrBlank() || + persistentDeviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + fun getDeviceName(context: Context, persistentDeviceId: String): String { + if ( + !SdkLevel.isAtLeastV() || + persistentDeviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + ) { + return Settings.Global.getString(context.contentResolver, Settings.Global.DEVICE_NAME) + } + val vdm: VirtualDeviceManager = + context.getSystemService(VirtualDeviceManager::class.java) + ?: throw RuntimeException("VirtualDeviceManager not found") + val deviceName = + vdm.getDisplayNameForPersistentDeviceId(persistentDeviceId) + ?: DEFAULT_REMOTE_DEVICE_NAME + return deviceName.toString() + } + + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + fun getDefaultDevicePersistentDeviceId(): String = + if (!SdkLevel.isAtLeastV()) { + "default: ${ContextCompat.DEVICE_ID_DEFAULT}" + } else { + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + } + + /** + * Grants external device permissions to the specified package. Permissions will be extracted + * from the group name. + * + * @param app The current application + * @param persistentDeviceId The external device identifier + * @param packageName Name of the package to which permission needs to granted + * @param permissions Permissions that needs to be granted + * @param userSet Whether to mark the permission as user set + * + * TODO: b/328839130: This method is meant to use it on External Devices and on Device Aware + * permissions only. It does not follow the default device implementation because of the + * LightAppPermGroup requirement. The data class LightAppPermGroup is not available for + * external devices at present, hence the implementation differs. + */ + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + fun grantRuntimePermissionsWithPersistentDeviceId( + app: Application, + persistentDeviceId: String, + packageName: String, + permissions: Set<String>, + userSet: Boolean + ) { + if (!SdkLevel.isAtLeastV() || isDefaultDeviceId(persistentDeviceId)) { + return + } + permissions + .filter { isPermissionDeviceAware(it) } + .forEach { permission -> + grantRuntimePermissionWithPersistentDeviceId( + app, + persistentDeviceId, + packageName, + permission, + userSet + ) + } + } + + /** + * Grants the external device permission to the specified package + * + * @param app The current application + * @param persistentDeviceId The external device identifier + * @param packageName Name of the package to which permission needs to granted + * @param permission Permission that needs to be granted + * @param userSet Whether to mark the permission as user set + * + * TODO: b/328839130: This method is meant to use it on External Devices and on Device Aware + * permissions only. It does not follow the default device implementation because of the + * LightAppPermGroup requirement. The data class LightAppPermGroup is not available for + * external devices at present, hence the implementation differs. + */ + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + private fun grantRuntimePermissionWithPersistentDeviceId( + app: Application, + persistentDeviceId: String, + packageName: String, + permission: String, + userSet: Boolean + ) { + if (!SdkLevel.isAtLeastV() || isDefaultDeviceId(persistentDeviceId)) { + return + } + val permissionManager = app.getSystemService(PermissionManager::class.java)!! + var newFlag = + FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED or + FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED + if (userSet) { + newFlag = newFlag or FLAG_PERMISSION_USER_SET + } + permissionManager.updatePermissionFlags( + packageName, + permission, + persistentDeviceId, + DEVICE_AWARE_PERMISSION_FLAG_MASK, + newFlag + ) + permissionManager.grantRuntimePermission(packageName, permission, persistentDeviceId) + } + + /** + * Revokes the external device permissions from the specified package. Permissions will be + * extracted from the group name. + * + * @param app The current application + * @param persistentDeviceId The external device identifier + * @param packageName Name of the package to which permission needs to revoked + * @param permissions Permissions that needs to be revoked + * @param userSet Whether to mark the permission as user set + * @param oneTime Whether this is a one-time permission grant permissions + * @param reason The reason for the revoke, or {@code null} for unspecified + * + * TODO: b/328839130: This method is meant to use it on External Devices and on Device Aware + * permissions only. It does not follow the default device implementation because of the + * LightAppPermGroup requirement. The data class LightAppPermGroup is not available for + * external devices at present, hence the implementation differs. + */ + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + fun revokeRuntimePermissionsWithPersistentDeviceId( + app: Application, + persistentDeviceId: String, + packageName: String, + permissions: Set<String>, + userSet: Boolean, + oneTime: Boolean, + reason: String? = null + ) { + if (!SdkLevel.isAtLeastV() || isDefaultDeviceId(persistentDeviceId)) { + return + } + permissions + .filter { isPermissionDeviceAware(it) } + .forEach { permission -> + revokeRuntimePermissionWithPersistentDeviceId( + app, + persistentDeviceId, + packageName, + permission, + userSet, + oneTime, + reason + ) + } + } + + /** + * Revokes the external device permission to the specified package. + * + * @param app The current application + * @param persistentDeviceId The external device identifier + * @param packageName Name of the package to which permission needs to revoked + * @param permission Permission that needs to be revoked + * @param userSet Whether to mark the permission as user set + * @param oneTime Whether this is a one-time permission grant permissions + * @param reason The reason for the revoke, or {@code null} for unspecified + * + * TODO: b/328839130: This method is meant to use it on External Devices and on Device Aware + * permissions only. It does not follow the default device implementation because of the + * LightAppPermGroup requirement. The data class LightAppPermGroup is not available for + * external devices at present, hence the implementation differs. + */ + @JvmStatic + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + private fun revokeRuntimePermissionWithPersistentDeviceId( + app: Application, + persistentDeviceId: String, + packageName: String, + permission: String, + userSet: Boolean, + oneTime: Boolean, + reason: String? = null + ) { + if (!SdkLevel.isAtLeastV() || isDefaultDeviceId(persistentDeviceId)) { + return + } + val permissionManager = app.getSystemService(PermissionManager::class.java)!! + var newFlag = + FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED or + FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED + if (oneTime) { + newFlag = newFlag or FLAG_PERMISSION_ONE_TIME + } + if (userSet) { + newFlag = newFlag or FLAG_PERMISSION_USER_SET + } + if (isPermissionUserFixed(app, persistentDeviceId, packageName, permission) && !oneTime) { + newFlag = newFlag or FLAG_PERMISSION_USER_FIXED + } + permissionManager.updatePermissionFlags( + packageName, + permission, + persistentDeviceId, + DEVICE_AWARE_PERMISSION_FLAG_MASK, + newFlag + ) + permissionManager.revokeRuntimePermission( + packageName, + permission, + persistentDeviceId, + reason + ) + } + + /** + * Determines if the permission is UserFixed. This method is for to use with V and above only. + * Supports both external and default devices, need to specify persistentDeviceId accordingly. + */ + @ChecksSdkIntAtLeast(Build.VERSION_CODES.VANILLA_ICE_CREAM) + private fun isPermissionUserFixed( + app: Application, + persistentDeviceId: String, + packageName: String, + permission: String + ): Boolean { + if (!SdkLevel.isAtLeastV()) { + return true + } + val permissionManager = app.getSystemService(PermissionManager::class.java)!! + val flags = + permissionManager.getPermissionFlags(packageName, permission, persistentDeviceId) + return flags and FLAG_PERMISSION_USER_FIXED != 0 + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/pm/data/model/PackageInfoModel.kt b/PermissionController/src/com/android/permissioncontroller/pm/data/model/PackageInfoModel.kt new file mode 100644 index 000000000..aecc18e66 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/pm/data/model/PackageInfoModel.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.pm.data.model + +import android.content.pm.PackageInfo + +/** A model/data class representing [PackageInfo] class. */ +data class PackageInfoModel( + val packageName: String, + val requestedPermissions: List<String> = emptyList(), + val requestedPermissionsFlags: List<Int> = emptyList(), + val applicationFlags: Int = 0, +) { + constructor( + packageInfo: PackageInfo + ) : this( + packageInfo.packageName, + packageInfo.requestedPermissions?.toList() ?: emptyList(), + packageInfo.requestedPermissionsFlags?.toList() ?: emptyList(), + requireNotNull(packageInfo.applicationInfo).flags + ) +} diff --git a/PermissionController/src/com/android/permissioncontroller/pm/data/repository/PackageRepository.kt b/PermissionController/src/com/android/permissioncontroller/pm/data/repository/PackageRepository.kt new file mode 100644 index 000000000..46a843d15 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/pm/data/repository/PackageRepository.kt @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.pm.data.repository + +import android.app.Application +import android.content.pm.PackageManager +import android.os.UserHandle +import android.util.Log +import com.android.permissioncontroller.permission.utils.Utils +import com.android.permissioncontroller.pm.data.model.PackageInfoModel +import kotlin.concurrent.Volatile +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * Repository to access package info data exposed by [PackageManager]. Domain and view layer + * shouldn't access [PackageManager] directly, instead they should use the repository. + */ +interface PackageRepository { + suspend fun getPackageInfo( + packageName: String, + user: UserHandle, + flags: Int = PackageManager.GET_PERMISSIONS + ): PackageInfoModel? + + companion object { + @Volatile private var instance: PackageRepository? = null + + fun getInstance(app: Application): PackageRepository = + instance ?: synchronized(this) { PackageRepositoryImpl(app).also { instance = it } } + } +} + +class PackageRepositoryImpl( + private val app: Application, + private val dispatcher: CoroutineDispatcher = Dispatchers.Default, +) : PackageRepository { + override suspend fun getPackageInfo( + packageName: String, + user: UserHandle, + flags: Int + ): PackageInfoModel? = + withContext(dispatcher) { + try { + val packageInfo = + Utils.getUserContext(app, user) + .packageManager + .getPackageInfo(packageName, PackageManager.GET_PERMISSIONS) + PackageInfoModel(packageInfo) + } catch (e: PackageManager.NameNotFoundException) { + Log.w(LOG_TAG, "package $packageName not found for user ${user.identifier}") + null + } + } + + companion object { + private const val LOG_TAG = "PackageRepository" + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/privacysources/AccessibilitySourceService.kt b/PermissionController/src/com/android/permissioncontroller/privacysources/AccessibilitySourceService.kt index da20727c5..c633c013a 100644 --- a/PermissionController/src/com/android/permissioncontroller/privacysources/AccessibilitySourceService.kt +++ b/PermissionController/src/com/android/permissioncontroller/privacysources/AccessibilitySourceService.kt @@ -76,8 +76,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -@VisibleForTesting -const val PROPERTY_SC_ACCESSIBILITY_SOURCE_ENABLED = "sc_accessibility_source_enabled" const val PROPERTY_SC_ACCESSIBILITY_LISTENER_ENABLED = "sc_accessibility_listener_enabled" const val SC_ACCESSIBILITY_SOURCE_ID = "AndroidAccessibility" const val SC_ACCESSIBILITY_REMOVE_ACCESS_ACTION_ID = "revoke_accessibility_app_access" @@ -88,14 +86,6 @@ private fun isAccessibilitySourceSupported(): Boolean { return SdkLevel.isAtLeastT() } -fun isAccessibilitySourceEnabled(): Boolean { - return DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_PRIVACY, - PROPERTY_SC_ACCESSIBILITY_SOURCE_ENABLED, - true - ) -} - /** cts test needs to disable the listener. */ fun isAccessibilityListenerEnabled(): Boolean { return DeviceConfig.getBoolean( @@ -907,11 +897,8 @@ class AccessibilityJobService : JobService() { Log.i(LOG_TAG, "Accessibility privacy source job already running") return false } - if ( - !isAccessibilitySourceEnabled() || - !isSafetyCenterEnabled(this@AccessibilityJobService) - ) { - Log.i(LOG_TAG, "either privacy source or safety center is not enabled") + if (!isSafetyCenterEnabled(this@AccessibilityJobService)) { + Log.i(LOG_TAG, "safety center is not enabled") jobFinished(params, false) mCurrentJob = null return false @@ -964,9 +951,7 @@ class SafetyCenterAccessibilityListener(val context: Context) : return } - if ( - !isAccessibilitySourceEnabled() || !isSafetyCenterEnabled(context) || isProfile(context) - ) { + if (!isSafetyCenterEnabled(context) || isProfile(context)) { Log.i(LOG_TAG, "accessibility event occurred, safety center feature not enabled.") return } diff --git a/PermissionController/src/com/android/permissioncontroller/role/Role.md b/PermissionController/src/com/android/permissioncontroller/role/Role.md index bde9f86f0..acdfffb50 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/Role.md +++ b/PermissionController/src/com/android/permissioncontroller/role/Role.md @@ -65,6 +65,10 @@ title. This attribute is required if the role is `visible`. Android S. This attribute is optional and defaults to `Build.VERSION_CODES.CUR_DEVELOPMENT`. - `minSdkVersion`: The minimum SDK version for the role to be available (inclusive), e.g. `31` for Android S. This attribute is optional and defaults to `Build.VERSION_CODES.BASE`. +- `onlyGrantWhenAdded`: Whether the role should only grant privileges when a role holder is actively +added. This attribute is optional and defaults to `false`. +- `overrideUserWhenGranting`: Whether the role should override user's choice about privileges when +granting. This attribute is optional and defaults to `false`. - `requestDescription`: The string resource for the description in the request role dialog, e.g. `@string/role_sms_request_description`, which says "Gets access to contacts, SMS, phone". This description should describe to the user the privileges that are going to be granted, and should not diff --git a/PermissionController/src/com/android/permissioncontroller/role/data/repository/RoleRepository.kt b/PermissionController/src/com/android/permissioncontroller/role/data/repository/RoleRepository.kt new file mode 100644 index 000000000..a514cdbb1 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/role/data/repository/RoleRepository.kt @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.role.data.repository + +import android.app.Application +import android.app.role.RoleManager +import kotlin.concurrent.Volatile +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * This repository encapsulates roles data (i.e. querying/adding role holders) exposed by + * [RoleManager]. + */ +interface RoleRepository { + /** + * @return Set of package names, the usage of private data by these packages is not shown in the + * privacy dashboard. + */ + suspend fun getExemptedPackages(): Set<String> + + companion object { + @Volatile private var instance: RoleRepository? = null + + fun getInstance(application: Application): RoleRepository = + instance + ?: synchronized(this) { RoleRepositoryImpl(application).also { instance = it } } + } +} + +class RoleRepositoryImpl(application: Application) : RoleRepository { + private val roleManager = application.getSystemService(RoleManager::class.java)!! + + override suspend fun getExemptedPackages(): Set<String> = + withContext(Dispatchers.Default) { + return@withContext buildSet { + add(OS_PKG) + addAll(EXEMPTED_ROLES.map { role -> roleManager.getRoleHolders(role) }.flatten()) + } + } + + companion object { + private const val OS_PKG = "android" + private const val SYSTEM_AMBIENT_AUDIO_INTELLIGENCE = + "android.app.role.SYSTEM_AMBIENT_AUDIO_INTELLIGENCE" + private const val SYSTEM_UI_INTELLIGENCE = "android.app.role.SYSTEM_UI_INTELLIGENCE" + private const val SYSTEM_AUDIO_INTELLIGENCE = "android.app.role.SYSTEM_AUDIO_INTELLIGENCE" + private const val SYSTEM_NOTIFICATION_INTELLIGENCE = + "android.app.role.SYSTEM_NOTIFICATION_INTELLIGENCE" + private const val SYSTEM_TEXT_INTELLIGENCE = "android.app.role.SYSTEM_TEXT_INTELLIGENCE" + private const val SYSTEM_VISUAL_INTELLIGENCE = "android.app.role.SYSTEM_VISUAL_INTELLIGENCE" + + private val EXEMPTED_ROLES = + arrayOf( + SYSTEM_AMBIENT_AUDIO_INTELLIGENCE, + SYSTEM_UI_INTELLIGENCE, + SYSTEM_AUDIO_INTELLIGENCE, + SYSTEM_NOTIFICATION_INTELLIGENCE, + SYSTEM_TEXT_INTELLIGENCE, + SYSTEM_VISUAL_INTELLIGENCE + ) + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/CheckableLinearLayout.java b/PermissionController/src/com/android/permissioncontroller/role/ui/CheckableLinearLayout.java index b396c3b7b..32a0bb20b 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/CheckableLinearLayout.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/CheckableLinearLayout.java @@ -100,12 +100,10 @@ public class CheckableLinearLayout extends LinearLayout implements Checkable { int count = viewGroup.getChildCount(); for (int i = 0; i < count; i++) { View child = viewGroup.getChildAt(i); - if (child.isDuplicateParentStateEnabled()) { - if (child instanceof Checkable) { - ((Checkable) child).setChecked(checked); - } else if (child instanceof ViewGroup) { - updateChildrenChecked((ViewGroup) child, checked); - } + if (child instanceof Checkable) { + ((Checkable) child).setChecked(checked); + } else if (child instanceof ViewGroup) { + updateChildrenChecked((ViewGroup) child, checked); } } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java index a8b16c521..145031b63 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java @@ -214,6 +214,8 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat preference.setChecked(checked); if (applicationInfo != null) { + roleApplicationPreference.setRestrictionIntent( + mRole.getApplicationRestrictionIntentAsUser(applicationInfo, mUser, context)); RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, roleApplicationPreference, applicationInfo, mUser, context); } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java index f9a0193bd..4fbe0ef33 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java @@ -65,6 +65,8 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat DefaultAppListChildFragment.class.getName() + ".preference.MANAGE_DOMAIN_URLS"; private static final String PREFERENCE_KEY_WORK_CATEGORY = DefaultAppListChildFragment.class.getName() + ".preference.WORK_CATEGORY"; + private static final String PREFERENCE_KEY_PRIVATE_CATEGORY = + DefaultAppListChildFragment.class.getName() + ".preference.PRIVATE_CATEGORY"; @NonNull private DefaultAppListViewModel mViewModel; @@ -88,6 +90,9 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat if (mViewModel.hasWorkProfile()) { mViewModel.getWorkLiveData().observe(this, roleItems -> onRoleListChanged()); } + if (mViewModel.hasPrivateProfile()) { + mViewModel.getPrivateLiveData().observe(this, roleItems -> onRoleListChanged()); + } } private void onRoleListChanged() { @@ -103,6 +108,14 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat return; } } + boolean hasPrivateProfile = mViewModel.hasPrivateProfile(); + List<RoleItem> privateRoleItems = null; + if (hasPrivateProfile) { + privateRoleItems = mViewModel.getPrivateLiveData().getValue(); + if (privateRoleItems == null) { + return; + } + } PF preferenceFragment = requirePreferenceFragment(); PreferenceManager preferenceManager = preferenceFragment.getPreferenceManager(); @@ -111,17 +124,22 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat ArrayMap<String, Preference> oldPreferences = new ArrayMap<>(); PreferenceCategory oldWorkPreferenceCategory = null; ArrayMap<String, Preference> oldWorkPreferences = new ArrayMap<>(); + PreferenceCategory oldPrivatePreferenceCategory = null; + ArrayMap<String, Preference> oldPrivatePreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); preferenceFragment.setPreferenceScreen(preferenceScreen); } else { - oldWorkPreferenceCategory = preferenceScreen.findPreference( - PREFERENCE_KEY_WORK_CATEGORY); - if (oldWorkPreferenceCategory != null) { - clearPreferences(oldWorkPreferenceCategory, oldWorkPreferences); - preferenceScreen.removePreference(oldWorkPreferenceCategory); - oldWorkPreferenceCategory.setOrder(Preference.DEFAULT_ORDER); - } + oldWorkPreferenceCategory = + preferenceScreen.findPreference(PREFERENCE_KEY_WORK_CATEGORY); + clearPreferenceCategory( + oldWorkPreferenceCategory, preferenceScreen, oldWorkPreferences); + + oldPrivatePreferenceCategory = + preferenceScreen.findPreference(PREFERENCE_KEY_PRIVATE_CATEGORY); + clearPreferenceCategory( + oldPrivatePreferenceCategory, preferenceScreen, oldPrivatePreferences); + clearPreferences(preferenceScreen, oldPreferences); } @@ -130,22 +148,34 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat addMoreDefaultAppsPreference(preferenceScreen, oldPreferences, context); addManageDomainUrlsPreference(preferenceScreen, oldPreferences, context); if (hasWorkProfile && !workRoleItems.isEmpty()) { - PreferenceCategory workPreferenceCategory = oldWorkPreferenceCategory; - if (workPreferenceCategory == null) { - workPreferenceCategory = new PreferenceCategory(context); - workPreferenceCategory.setKey(PREFERENCE_KEY_WORK_CATEGORY); - workPreferenceCategory.setTitle(Utils.getEnterpriseString(context, - DefaultAppSettings.WORK_PROFILE_DEFAULT_APPS_TITLE, - R.string.default_apps_for_work)); - } - preferenceScreen.addPreference(workPreferenceCategory); - addPreferences(workPreferenceCategory, workRoleItems, oldWorkPreferences, this, + String workTitle = Utils.getEnterpriseString(context, + DefaultAppSettings.WORK_PROFILE_DEFAULT_APPS_TITLE, + R.string.default_apps_for_work); + addPreferenceCategory(oldWorkPreferenceCategory, PREFERENCE_KEY_WORK_CATEGORY, + workTitle, preferenceScreen, workRoleItems, oldWorkPreferences, this, mViewModel.getWorkProfile(), context); } + if (hasPrivateProfile && !privateRoleItems.isEmpty()) { + String privateTitle = context.getString(R.string.default_apps_for_private_profile); + addPreferenceCategory(oldPrivatePreferenceCategory, PREFERENCE_KEY_PRIVATE_CATEGORY, + privateTitle, preferenceScreen, privateRoleItems, oldPrivatePreferences, this, + mViewModel.getPrivateProfile(), context); + } preferenceFragment.onPreferenceScreenChanged(); } + private static void clearPreferenceCategory(@Nullable PreferenceCategory preferenceCategory, + @NonNull PreferenceScreen preferenceScreen, + @NonNull ArrayMap<String, Preference> oldPreferences) { + if (preferenceCategory == null) { + return; + } + clearPreferences(preferenceCategory, oldPreferences); + preferenceScreen.removePreference(preferenceCategory); + preferenceCategory.setOrder(Preference.DEFAULT_ORDER); + } + private static void clearPreferences(@NonNull PreferenceGroup preferenceGroup, @NonNull ArrayMap<String, Preference> oldPreferences) { for (int i = preferenceGroup.getPreferenceCount() - 1; i >= 0; --i) { @@ -157,6 +187,24 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat } } + @NonNull + private void addPreferenceCategory( + @Nullable PreferenceCategory oldPreferenceCategory, @NonNull String key, + @Nullable String title, @NonNull PreferenceScreen preferenceScreen, + @NonNull List<RoleItem> roleItems, @NonNull ArrayMap<String, Preference> oldPreferences, + @NonNull Preference.OnPreferenceClickListener listener, + @NonNull UserHandle user, @NonNull Context context) { + PreferenceCategory preferenceCategory = oldPreferenceCategory; + if (preferenceCategory == null) { + preferenceCategory = new PreferenceCategory(context); + preferenceCategory.setKey(key); + preferenceCategory.setTitle(title); + } + preferenceScreen.addPreference(preferenceCategory); + addPreferences(preferenceCategory, roleItems, oldPreferences, listener, + user, context); + } + private void addPreferences(@NonNull PreferenceGroup preferenceGroup, @NonNull List<RoleItem> roleItems, @NonNull ArrayMap<String, Preference> oldPreferences, @NonNull Preference.OnPreferenceClickListener listener, @NonNull UserHandle user, @@ -182,6 +230,7 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat preference = rolePreference.asPreference(); } + rolePreference.setRestrictionIntent(role.getRestrictionIntentAsUser(user, context)); List<ApplicationInfo> holderApplicationInfos = roleItem.getHolderApplicationInfos(); if (holderApplicationInfos.isEmpty()) { preference.setIcon(null); @@ -191,7 +240,8 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat preference.setIcon(Utils.getBadgedIcon(context, holderApplicationInfo)); preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context)); } - RoleUiBehaviorUtils.preparePreferenceAsUser(role, rolePreference, user, context); + RoleUiBehaviorUtils.preparePreferenceAsUser(role, holderApplicationInfos, + rolePreference, user, context); preferenceGroup.addPreference(preference); } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListViewModel.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListViewModel.java index 06f58ef25..5bc25df54 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListViewModel.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListViewModel.java @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui; import android.app.Application; import android.os.Process; import android.os.UserHandle; +import android.os.UserManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -27,6 +28,7 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; +import com.android.permissioncontroller.permission.utils.Utils; import com.android.permissioncontroller.role.utils.UserUtils; import java.util.List; @@ -44,6 +46,10 @@ public class DefaultAppListViewModel extends AndroidViewModel { private final UserHandle mWorkProfile; @Nullable private final LiveData<List<RoleItem>> mWorkLiveData; + @Nullable + private final UserHandle mPrivateProfile; + @Nullable + private final LiveData<List<RoleItem>> mPrivateLiveData; public DefaultAppListViewModel(@NonNull Application application) { super(application); @@ -55,6 +61,16 @@ public class DefaultAppListViewModel extends AndroidViewModel { mWorkProfile = UserUtils.getWorkProfile(application); mWorkLiveData = mWorkProfile != null ? Transformations.map(new RoleListLiveData(true, mWorkProfile, application), sortFunction) : null; + + UserHandle privateProfile = UserUtils.getPrivateProfile(application); + if (privateProfile != null && Utils.shouldShowInSettings( + privateProfile, application.getSystemService(UserManager.class))) { + mPrivateProfile = privateProfile; + } else { + mPrivateProfile = null; + } + mPrivateLiveData = mPrivateProfile != null ? Transformations.map(new RoleListLiveData(true, + mPrivateProfile, application), sortFunction) : null; } @NonNull @@ -85,4 +101,33 @@ public class DefaultAppListViewModel extends AndroidViewModel { public LiveData<List<RoleItem>> getWorkLiveData() { return mWorkLiveData; } + + /** + * Check whether the user has a private profile. + * + * @return whether the user has a private profile. + */ + public boolean hasPrivateProfile() { + return mPrivateProfile != null; + } + + /** + * Returns the private profile belonging to the user, if any. + * + * @return the private profile, if it exists. null otherwise. + */ + @Nullable + public UserHandle getPrivateProfile() { + return mPrivateProfile; + } + + /** + * Returns the data corresponding to the private profile, if one exists. + * + * @return data corresponding to the private profile, if it exists. null otherwise. + */ + @Nullable + public LiveData<List<RoleItem>> getPrivateLiveData() { + return mPrivateLiveData; + } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java index 279e55266..db65cd9b7 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleActivity.java @@ -16,6 +16,8 @@ package com.android.permissioncontroller.role.ui; +import static com.android.permissioncontroller.Constants.EXTRA_IS_ECM_IN_APP; + import android.app.role.RoleManager; import android.content.Context; import android.content.Intent; @@ -136,7 +138,8 @@ public class RequestRoleActivity extends FragmentActivity { return; } - if (PackageUtils.getApplicationInfo(mPackageName, this) == null) { + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(mPackageName, this); + if (applicationInfo == null) { Log.w(LOG_TAG, "Unknown application: " + mPackageName); reportRequestResult( PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); @@ -166,6 +169,19 @@ public class RequestRoleActivity extends FragmentActivity { return; } + Intent restrictionIntent = role.getApplicationRestrictionIntentAsUser(applicationInfo, + Process.myUserHandle(), this); + if (restrictionIntent != null) { + Log.w(LOG_TAG, "Cannot request role due to enhanced confirmation restriction" + + ", role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED_ENHANCED_CONFIRMATION_RESTRICTION); + restrictionIntent.putExtra(EXTRA_IS_ECM_IN_APP, true); + startActivity(restrictionIntent); + finish(); + return; + } + if (!role.isPackageQualifiedAsUser(mPackageName, Process.myUserHandle(), this)) { Log.w(LOG_TAG, "Application doesn't qualify for role, role: " + mRoleName + ", package: " + mPackageName); diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java index 80834a3e2..fb3a46d6a 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java @@ -35,7 +35,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; -import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.ImageView; @@ -54,6 +53,8 @@ import com.android.permissioncontroller.permission.utils.PackageRemovalMonitor; import com.android.permissioncontroller.permission.utils.Utils; import com.android.permissioncontroller.role.model.UserDeniedManager; import com.android.permissioncontroller.role.utils.PackageUtils; +import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils; +import com.android.permissioncontroller.role.utils.UiUtils; import com.android.role.controller.model.Role; import com.android.role.controller.model.Roles; @@ -154,7 +155,6 @@ public class RequestRoleFragment extends DialogFragment { View viewLayout = inflater.inflate(R.layout.request_role_view, null); mListView = viewLayout.requireViewById(R.id.list); - mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); mListView.setOnItemClickListener((parent, view, position, id) -> onItemClicked(position)); mAdapter = new Adapter(mListView, mRole); if (savedInstanceState != null) { @@ -414,9 +414,9 @@ public class RequestRoleFragment extends DialogFragment { // Skip the "None" item. continue; } - ApplicationInfo qualifyingApplicationInfo = qualifyingApplication.first; - if (Objects.equals(qualifyingApplicationInfo.packageName, packageName)) { - return qualifyingApplicationInfo.uid; + ApplicationInfo applicationInfo = qualifyingApplication.first; + if (Objects.equals(applicationInfo.packageName, packageName)) { + return applicationInfo.uid; } } return -1; @@ -439,19 +439,7 @@ public class RequestRoleFragment extends DialogFragment { if (mAdapter == null) { return null; } - int count = mAdapter.getCount(); - for (int i = 0; i < count; i++) { - Pair<ApplicationInfo, Boolean> qualifyingApplication = mAdapter.getItem(i); - if (qualifyingApplication == null) { - // Skip the "None" item. - continue; - } - boolean isHolderApplication = qualifyingApplication.second; - if (isHolderApplication) { - return qualifyingApplication.first.packageName; - } - } - return null; + return mAdapter.mHolderPackageName; } static void reportRequestResult(int requestingUid, String requestingPackageName, @@ -477,8 +465,8 @@ public class RequestRoleFragment extends DialogFragment { private static final String STATE_USER_CHECKED = Adapter.class.getName() + ".state.USER_CHECKED"; - private static final String STATE_USER_CHECKED_PACKAGE_NAME = Adapter.class.getName() - + ".state.USER_CHECKED_PACKAGE_NAME"; + private static final String STATE_CHECKED_PACKAGE_NAME = Adapter.class.getName() + + ".state.CHECKED_PACKAGE_NAME"; private static final int LAYOUT_TRANSITION_DURATION_MILLIS = 150; @@ -493,7 +481,8 @@ public class RequestRoleFragment extends DialogFragment { private final List<Pair<ApplicationInfo, Boolean>> mQualifyingApplications = new ArrayList<>(); - private boolean mHasHolderApplication; + @Nullable + private String mHolderPackageName; private boolean mDontAskAgain; @@ -501,10 +490,8 @@ public class RequestRoleFragment extends DialogFragment { // the current holder as checked. private boolean mUserChecked; - private boolean mPendingUserChecked; - // We may use a null to represent the "None" item. @Nullable - private String mPendingUserCheckedPackageName; + private String mCheckedPackageName; Adapter(@NonNull ListView listView, @NonNull Role role) { mListView = listView; @@ -514,15 +501,14 @@ public class RequestRoleFragment extends DialogFragment { public void onSaveInstanceState(@NonNull Bundle outState) { outState.putBoolean(STATE_USER_CHECKED, mUserChecked); if (mUserChecked) { - outState.putString(STATE_USER_CHECKED_PACKAGE_NAME, getCheckedPackageName()); + outState.putString(STATE_CHECKED_PACKAGE_NAME, mCheckedPackageName); } } public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { - mPendingUserChecked = savedInstanceState.getBoolean(STATE_USER_CHECKED); - if (mPendingUserChecked) { - mPendingUserCheckedPackageName = savedInstanceState.getString( - STATE_USER_CHECKED_PACKAGE_NAME); + mUserChecked = savedInstanceState.getBoolean(STATE_USER_CHECKED); + if (mUserChecked) { + mCheckedPackageName = savedInstanceState.getString(STATE_CHECKED_PACKAGE_NAME); } } @@ -533,14 +519,28 @@ public class RequestRoleFragment extends DialogFragment { mDontAskAgain = dontAskAgain; if (mDontAskAgain) { mUserChecked = false; - updateItemChecked(); + mCheckedPackageName = mHolderPackageName; } notifyDataSetChanged(); } public void onItemClicked(int position) { - mUserChecked = true; - // We may need to change description based on checked state. + Pair<ApplicationInfo, Boolean> qualifyingApplication = getItem(position); + if (qualifyingApplication == null) { + mUserChecked = true; + mCheckedPackageName = null; + } else { + ApplicationInfo applicationInfo = qualifyingApplication.first; + Intent restrictionIntent = mRole.getApplicationRestrictionIntentAsUser( + applicationInfo, Process.myUserHandle(), mListView.getContext()); + if (restrictionIntent != null) { + mListView.getContext().startActivity(restrictionIntent); + return; + } else { + mUserChecked = true; + mCheckedPackageName = applicationInfo.packageName; + } + } notifyDataSetChanged(); } @@ -550,42 +550,10 @@ public class RequestRoleFragment extends DialogFragment { mQualifyingApplications.add(0, null); } mQualifyingApplications.addAll(qualifyingApplications); - mHasHolderApplication = hasHolderApplication(qualifyingApplications); - notifyDataSetChanged(); + mHolderPackageName = getHolderPackageName(qualifyingApplications); - if (mPendingUserChecked) { - restoreItemChecked(); - mPendingUserChecked = false; - mPendingUserCheckedPackageName = null; - } - - if (!mUserChecked) { - updateItemChecked(); - } - } - - private static boolean hasHolderApplication( - @NonNull List<Pair<ApplicationInfo, Boolean>> qualifyingApplications) { - int qualifyingApplicationsSize = qualifyingApplications.size(); - for (int i = 0; i < qualifyingApplicationsSize; i++) { - Pair<ApplicationInfo, Boolean> qualifyingApplication = qualifyingApplications.get( - i); - boolean isHolderApplication = qualifyingApplication.second; - - if (isHolderApplication) { - return true; - } - } - return false; - } - - private void restoreItemChecked() { - if (mPendingUserCheckedPackageName == null) { - if (mRole.shouldShowNone()) { - mUserChecked = true; - mListView.setItemChecked(0, true); - } - } else { + if (mUserChecked && mCheckedPackageName != null) { + boolean isCheckedPackageNameFound = false; int count = getCount(); for (int i = 0; i < count; i++) { Pair<ApplicationInfo, Boolean> qualifyingApplication = getItem(i); @@ -594,55 +562,52 @@ public class RequestRoleFragment extends DialogFragment { } String packageName = qualifyingApplication.first.packageName; - if (Objects.equals(packageName, mPendingUserCheckedPackageName)) { + if (Objects.equals(packageName, mCheckedPackageName)) { mUserChecked = true; - mListView.setItemChecked(i, true); + isCheckedPackageNameFound = true; break; } } + if (!isCheckedPackageNameFound) { + mUserChecked = false; + mCheckedPackageName = null; + } + } + + if (!mUserChecked) { + mCheckedPackageName = mHolderPackageName; } + + notifyDataSetChanged(); } - private void updateItemChecked() { - if (!mHasHolderApplication) { - if (mRole.shouldShowNone()) { - mListView.setItemChecked(0, true); - } else { - mListView.clearChoices(); + @Nullable + private static String getHolderPackageName( + @NonNull List<Pair<ApplicationInfo, Boolean>> qualifyingApplications) { + int qualifyingApplicationSize = qualifyingApplications.size(); + for (int i = 0; i < qualifyingApplicationSize; i++) { + Pair<ApplicationInfo, Boolean> qualifyingApplication = qualifyingApplications.get( + i); + if (qualifyingApplication == null) { + continue; } - } else { - int count = getCount(); - for (int i = 0; i < count; i++) { - Pair<ApplicationInfo, Boolean> qualifyingApplication = getItem(i); - if (qualifyingApplication == null) { - continue; - } - boolean isHolderApplication = qualifyingApplication.second; + ApplicationInfo applicationInfo = qualifyingApplication.first; + boolean isHolderApplication = qualifyingApplication.second; - if (isHolderApplication) { - mListView.setItemChecked(i, true); - break; - } + if (isHolderApplication) { + return applicationInfo.packageName; } } - } - - @Nullable - public Pair<ApplicationInfo, Boolean> getCheckedItem() { - int position = mListView.getCheckedItemPosition(); - return position != AdapterView.INVALID_POSITION ? getItem(position) : null; + return null; } @Nullable public String getCheckedPackageName() { - Pair<ApplicationInfo, Boolean> qualifyingApplication = getCheckedItem(); - return qualifyingApplication == null ? null : qualifyingApplication.first.packageName; + return mCheckedPackageName; } public boolean isHolderApplicationChecked() { - Pair<ApplicationInfo, Boolean> qualifyingApplication = getCheckedItem(); - return qualifyingApplication == null ? !mHasHolderApplication - : qualifyingApplication.second; + return Objects.equals(mCheckedPackageName, mHolderPackageName); } @Override @@ -684,7 +649,7 @@ public class RequestRoleFragment extends DialogFragment { } Pair<ApplicationInfo, Boolean> qualifyingApplication = getItem(position); if (qualifyingApplication == null) { - return !mHasHolderApplication; + return mHolderPackageName == null; } else { boolean isHolderApplication = qualifyingApplication.second; return isHolderApplication; @@ -695,13 +660,13 @@ public class RequestRoleFragment extends DialogFragment { @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { Context context = parent.getContext(); - View view = convertView; + CheckableLinearLayout view = (CheckableLinearLayout) convertView; ViewHolder holder; if (view != null) { holder = (ViewHolder) view.getTag(); } else { - view = LayoutInflater.from(context).inflate(R.layout.request_role_item, parent, - false); + view = (CheckableLinearLayout) LayoutInflater.from(context).inflate( + R.layout.request_role_item, parent, false); holder = new ViewHolder(view); view.setTag(holder); @@ -709,38 +674,50 @@ public class RequestRoleFragment extends DialogFragment { LAYOUT_TRANSITION_DURATION_MILLIS); } - view.setEnabled(isEnabled(position)); - Pair<ApplicationInfo, Boolean> qualifyingApplication = getItem(position); + ApplicationInfo applicationInfo; + boolean restricted; + boolean checked; Drawable icon; String title; String subtitle; if (qualifyingApplication == null) { + applicationInfo = null; + restricted = false; + checked = mCheckedPackageName == null; icon = AppCompatResources.getDrawable(context, R.drawable.ic_remove_circle); title = context.getString(R.string.default_app_none); - subtitle = !mHasHolderApplication ? context.getString( + subtitle = mHolderPackageName != null ? context.getString( R.string.request_role_current_default) : null; } else { - ApplicationInfo qualifyingApplicationInfo = qualifyingApplication.first; - icon = Utils.getBadgedIcon(context, qualifyingApplicationInfo); - title = Utils.getAppLabel(qualifyingApplicationInfo, context); + applicationInfo = qualifyingApplication.first; + restricted = mRole.getApplicationRestrictionIntentAsUser(applicationInfo, + Process.myUserHandle(), context) != null; + checked = Objects.equals(applicationInfo.packageName, mCheckedPackageName); + icon = Utils.getBadgedIcon(context, applicationInfo); + title = Utils.getAppLabel(applicationInfo, context); boolean isHolderApplication = qualifyingApplication.second; subtitle = isHolderApplication ? context.getString(R.string.request_role_current_default) - : mListView.isItemChecked(position) - ? context.getString(mRole.getRequestDescriptionResource()) : null; + : checked ? context.getString(mRole.getRequestDescriptionResource()) : null; } + boolean enabled = isEnabled(position); + UiUtils.setViewTreeEnabled(view, enabled && !restricted); + view.setEnabled(enabled); + view.setChecked(checked); holder.iconImage.setImageDrawable(icon); holder.titleText.setText(title); holder.subtitleText.setVisibility(!TextUtils.isEmpty(subtitle) ? View.VISIBLE : View.GONE); holder.subtitleText.setText(subtitle); + RoleUiBehaviorUtils.prepareRequestRoleItemViewAsUser(mRole, holder, applicationInfo, + Process.myUserHandle(), context); return view; } - private static class ViewHolder { + private static class ViewHolder implements RequestRoleItemView { @NonNull public final ImageView iconImage; @@ -757,6 +734,21 @@ public class RequestRoleFragment extends DialogFragment { titleText = view.requireViewById(R.id.title); subtitleText = view.requireViewById(R.id.subtitle); } + + @Override + public ImageView getIconImageView() { + return iconImage; + } + + @Override + public TextView getTitleTextView() { + return titleText; + } + + @Override + public TextView getSubtitleTextView() { + return subtitleText; + } } } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleItemView.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleItemView.java new file mode 100644 index 000000000..25dea89ad --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleItemView.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.role.ui; + +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +/** + * Item view for qualifying applications in role requests. + */ +public interface RequestRoleItemView { + + /** + * Get the {@link ImageView} for item icon. + */ + @NonNull + ImageView getIconImageView(); + + /** + * Get the {@link TextView} for item title. + */ + @NonNull + TextView getTitleTextView(); + + /** + * Get the {@link TextView} for item subtitle. + */ + @NonNull + TextView getSubtitleTextView(); +} diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreference.java index e6bc9bab6..f68253161 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreference.java @@ -16,15 +16,17 @@ package com.android.permissioncontroller.role.ui; +import android.content.Intent; + import androidx.annotation.Nullable; /** - * Preference that is aware of user restrictions that can block them. + * Preference that is aware of restrictions that can block them. */ -public interface UserRestrictionAwarePreference { +public interface RestrictionAwarePreference { /** - * Specifies user restriction that blocks this preference. + * Set the restriction intent that blocks this preference. */ - void setUserRestriction(@Nullable String userRestriction); + void setRestrictionIntent(@Nullable Intent restrictionIntent); } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreferenceMixin.java index 033507991..8d757324f 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreferenceMixin.java @@ -16,9 +16,7 @@ package com.android.permissioncontroller.role.ui; -import android.app.admin.DevicePolicyManager; import android.content.Intent; -import android.provider.Settings; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -26,32 +24,35 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; /** - * Mixin for implementing {@link UserRestrictionAwarePreference}. + * Mixin for implementing {@link RestrictionAwarePreference}. */ -public class UserRestrictionAwarePreferenceMixin { +public class RestrictionAwarePreferenceMixin { + + private static final String LOG_TAG = RestrictionAwarePreferenceMixin.class.getSimpleName(); @NonNull private final Preference mPreference; + @Nullable - private String mUserRestriction = null; + private Intent mRestrictionIntent; - public UserRestrictionAwarePreferenceMixin(@NonNull Preference preference) { + public RestrictionAwarePreferenceMixin(@NonNull Preference preference) { mPreference = preference; } /** - * Implementation for {@link UserRestrictionAwarePreference#setUserRestriction}. + * Implementation for {@link RestrictionAwarePreference#setRestrictionIntent}. */ - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestriction = userRestriction; - mPreference.setEnabled(mUserRestriction == null); + public void setRestrictionIntent(@Nullable Intent restrictionIntent) { + mRestrictionIntent = restrictionIntent; + mPreference.setEnabled(mRestrictionIntent == null); } /** * Call after {@link Preference#onBindViewHolder} to apply blocking effects. */ public void onAfterBindViewHolder(@NonNull PreferenceViewHolder holder) { - if (mUserRestriction != null) { + if (mRestrictionIntent != null) { // We set the item view to enabled to make the preference row clickable. // Normal disabled preferences have the whole view hierarchy disabled, so by making only // the top-level itemView enabled, we don't change the fact that the whole preference @@ -60,10 +61,8 @@ public class UserRestrictionAwarePreferenceMixin { // we don't need to unset the listener here (we wouldn't know the correct one anyway). // This approach is used already by com.android.settingslib.RestrictedPreferenceHelper. holder.itemView.setEnabled(true); - Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS) - .putExtra(DevicePolicyManager.EXTRA_RESTRICTION, mUserRestriction); holder.itemView.setOnClickListener( - (view) -> holder.itemView.getContext().startActivity(intent)); + view -> view.getContext().startActivity(mRestrictionIntent)); } } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java index 1b5b27971..1d3e32c9c 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java @@ -22,7 +22,7 @@ import androidx.preference.TwoStatePreference; /** * Preference for application being a candidate or holding a role. */ -public interface RoleApplicationPreference extends UserRestrictionAwarePreference { +public interface RoleApplicationPreference extends RestrictionAwarePreference { /** * Get instance of {@code this} as {@link TwoStatePreference}. diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java index 442963ce6..bbc123cfe 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java @@ -16,14 +16,16 @@ package com.android.permissioncontroller.role.ui; +import androidx.annotation.NonNull; import androidx.preference.Preference; /** * Preference used by the default apps list UI. */ -public interface RolePreference extends TwoTargetPreference, UserRestrictionAwarePreference { +public interface RolePreference extends TwoTargetPreference, RestrictionAwarePreference { /** * Return this preference as {@link Preference}. */ + @NonNull Preference asPreference(); } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java index 3a8cd55d3..ab2387686 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/TwoTargetPreference.java @@ -41,6 +41,7 @@ public interface TwoTargetPreference { /** * Return this preference as {@link Preference}. */ + @NonNull Preference asPreference(); /** diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java index 83c146ebc..764c07497 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java @@ -17,25 +17,27 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; +import android.content.Intent; import android.widget.RadioButton; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.res.TypedArrayUtils; import androidx.preference.PreferenceViewHolder; import androidx.preference.TwoStatePreference; import com.android.permissioncontroller.R; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; /** Preference used to represent apps that can be picked as a default app. */ public class AutoRadioPreference extends TwoStatePreference implements RoleApplicationPreference { - private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); - public AutoRadioPreference(Context context) { + public AutoRadioPreference(@NonNull Context context) { super(context, null, TypedArrayUtils.getAttr(context, androidx.preference.R.attr.preferenceStyle, android.R.attr.preferenceStyle)); @@ -48,20 +50,21 @@ public class AutoRadioPreference extends TwoStatePreference implements } @Override - public void onBindViewHolder(PreferenceViewHolder holder) { + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); RadioButton radioButton = (RadioButton) holder.findViewById(R.id.radio_button); radioButton.setChecked(isChecked()); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setRestrictionIntent(@Nullable Intent restrictionIntent) { + mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } + @NonNull @Override public AutoRadioPreference asTwoStatePreference() { return this; diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java index d2f1b6cde..15fd117d1 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java @@ -17,16 +17,19 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; +import android.content.Intent; import android.util.AttributeSet; +import androidx.annotation.AttrRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RolePreference; import com.android.permissioncontroller.role.ui.TwoTargetPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; /** * Preference for use in auto lists. Extends {@link TwoTargetPreference} in order to make sure of @@ -34,16 +37,16 @@ import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMi */ public class AutoRolePreference extends Preference implements RolePreference { - private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public AutoRolePreference(@NonNull Context context, - @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } public AutoRolePreference(@NonNull Context context, @Nullable AttributeSet attrs, - int defStyleAttr) { + @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); } @@ -56,21 +59,21 @@ public class AutoRolePreference extends Preference implements RolePreference { } @Override - public void setOnSecondTargetClickListener(@Nullable OnSecondTargetClickListener listener) { - } + public void setOnSecondTargetClickListener(@Nullable OnSecondTargetClickListener listener) {} @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setRestrictionIntent(@Nullable Intent restrictionIntent) { + mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @Override - public void onBindViewHolder(PreferenceViewHolder holder) { + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } + @NonNull @Override public AutoRolePreference asPreference() { return this; diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java index 900e58551..bfb2b5d1d 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; +import android.content.Intent; import android.util.AttributeSet; import androidx.annotation.AttrRes; @@ -26,8 +27,8 @@ import androidx.annotation.StyleRes; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; /** * Role application preference represented as a switch. @@ -35,8 +36,8 @@ import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMi public class AutoSwitchPreference extends SwitchPreference implements RoleApplicationPreference { - private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public AutoSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { @@ -57,15 +58,15 @@ public class AutoSwitchPreference extends SwitchPreference } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setRestrictionIntent(@Nullable Intent restrictionIntent) { + mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @Override - public void onBindViewHolder(PreferenceViewHolder holder) { + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @NonNull diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java index 323325d0b..0142e1c40 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/HomeRoleUiBehavior.java @@ -38,6 +38,8 @@ import com.android.permissioncontroller.role.ui.TwoTargetPreference; import com.android.permissioncontroller.role.utils.UserUtils; import com.android.role.controller.model.Role; +import java.util.List; + /*** * Class for UI behavior of Home role */ @@ -47,7 +49,8 @@ public class HomeRoleUiBehavior implements RoleUiBehavior { @Override public void preparePreferenceAsUser(@NonNull Role role, @NonNull TwoTargetPreference preference, - @NonNull UserHandle user, @NonNull Context context) { + @NonNull List<ApplicationInfo> applicationInfos, @NonNull UserHandle user, + @NonNull Context context) { TwoTargetPreference.OnSecondTargetClickListener listener = null; RoleManager roleManager = context.getSystemService(RoleManager.class); String packageName = CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser( diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java index 29dc5d2fc..ae5c03676 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/RoleUiBehavior.java @@ -25,15 +25,31 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.Preference; +import com.android.permissioncontroller.role.ui.RequestRoleItemView; import com.android.permissioncontroller.role.ui.TwoTargetPreference; import com.android.role.controller.model.Role; +import java.util.List; + /*** * Interface for UI behavior for roles */ public interface RoleUiBehavior { /** + * Prepare a {@link RequestRoleItemView} for this role and an application. + * + * @param role the role to prepare the preference for + * @param itemView the {@link RequestRoleItemView} for the application + * @param applicationInfo the {@link ApplicationInfo} for the application + * @param user the user for this role + * @param context the {@code Context} to retrieve system services + */ + default void prepareRequestRoleItemViewAsUser(@NonNull Role role, + @NonNull RequestRoleItemView itemView, @NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, @NonNull Context context) {} + + /** * Get the {@link Intent} to manage this role, or {@code null} to use the default UI. * * @param role the role to get the intent for @@ -53,19 +69,21 @@ public interface RoleUiBehavior { * * @param role the role to prepare the preference for * @param preference the {@link Preference} for this role + * @param applicationInfos a list {@link ApplicationInfo} for the current role holders * @param user the user for this role * @param context the {@code Context} to retrieve system services */ default void preparePreferenceAsUser(@NonNull Role role, @NonNull TwoTargetPreference preference, - @NonNull UserHandle user, - @NonNull Context context) {} + @NonNull List<ApplicationInfo> applicationInfos, + @NonNull UserHandle user, @NonNull Context context) {} /** - * Prepare a {@link Preference} for this role. + * Prepare a {@link Preference} for this role and an application. * * @param role the role to prepare the preference for - * @param preference the {@link Preference} for this role + * @param preference the {@link Preference} for the application + * @param applicationInfo the {@link ApplicationInfo} for the application * @param user the user for this role * @param context the {@code Context} to retrieve system services */ diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/v35/WalletRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/v35/WalletRoleUiBehavior.java new file mode 100644 index 000000000..aa6194997 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/v35/WalletRoleUiBehavior.java @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.role.ui.behavior.v35; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.nfc.cardemulation.ApduServiceInfo; +import android.nfc.cardemulation.CardEmulation; +import android.nfc.cardemulation.HostApduService; +import android.nfc.cardemulation.OffHostApduService; +import android.os.Build; +import android.os.UserHandle; +import android.text.TextUtils; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.core.util.Pair; +import androidx.preference.Preference; + +import com.android.permissioncontroller.role.ui.TwoTargetPreference; +import com.android.permissioncontroller.role.ui.behavior.RoleUiBehavior; +import com.android.role.controller.model.Role; +import com.android.role.controller.util.UserUtils; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/*** + * Class for UI behavior of Wallet role + */ +@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) +public class WalletRoleUiBehavior implements RoleUiBehavior { + + private static final String LOG_TAG = WalletRoleUiBehavior.class.getSimpleName(); + + @Override + public void preparePreferenceAsUser(@NonNull Role role, @NonNull TwoTargetPreference preference, + @NonNull List<ApplicationInfo> applicationInfos, @NonNull UserHandle user, + @NonNull Context context) { + Context userContext = UserUtils.getUserContext(context, user); + if (!applicationInfos.isEmpty()) { + preparePreferenceInternal(preference.asPreference(), applicationInfos.get(0), + false, user, userContext); + } + } + + @Override + public void prepareApplicationPreferenceAsUser(@NonNull Role role, + @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, @NonNull Context context) { + Context userContext = UserUtils.getUserContext(context, user); + preparePreferenceInternal(preference, applicationInfo, true, user, userContext); + } + + private void preparePreferenceInternal(@NonNull Preference preference, + @NonNull ApplicationInfo applicationInfo, boolean setTitle, @NonNull UserHandle user, + @NonNull Context context) { + if (isSystemApplication(applicationInfo)) { + List<ApduServiceInfo> serviceInfos = getNfcServicesForPackage( + applicationInfo.packageName, user, context); + + Pair<Drawable, CharSequence> bannerAndLabel = + getNonPaymentServiceBannerAndLabelIfExists(serviceInfos, user, context); + if (bannerAndLabel != null) { + preference.setIcon(bannerAndLabel.first); + if (setTitle) { + preference.setTitle(bannerAndLabel.second); + } else { + preference.setSummary(bannerAndLabel.second); + } + } + } + } + + @NonNull + private static List<ApduServiceInfo> getNfcServicesForPackage(@NonNull String packageName, + @NonNull UserHandle user, @NonNull Context context) { + PackageManager packageManager = context.getPackageManager(); + Intent hostApduIntent = new Intent(HostApduService.SERVICE_INTERFACE); + Intent offHostApduIntent = new Intent(OffHostApduService.SERVICE_INTERFACE); + hostApduIntent.setPackage(packageName); + offHostApduIntent.setPackage(packageName); + List<ResolveInfo> hostApduServices = packageManager.queryIntentServicesAsUser( + hostApduIntent, + PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA + | PackageManager.MATCH_DISABLED_COMPONENTS), user); + List<ResolveInfo> offHostApduServices = packageManager.queryIntentServicesAsUser( + offHostApduIntent, + PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA + | PackageManager.MATCH_DISABLED_COMPONENTS), user); + List<ApduServiceInfo> nfcServices = new ArrayList<>(); + int apduServiceInfoSize = hostApduServices.size(); + for (int i = 0; i < apduServiceInfoSize; i++) { + ResolveInfo resolveInfo = hostApduServices.get(i); + ApduServiceInfo apduServiceInfo; + try { + apduServiceInfo = new ApduServiceInfo(packageManager, resolveInfo, true); + } catch (XmlPullParserException | IOException e) { + Log.e(LOG_TAG, "Error creating the apduserviceinfo.", e); + continue; + } + nfcServices.add(apduServiceInfo); + } + int offHostApduServiceInfoSize = offHostApduServices.size(); + for (int i = 0; i < offHostApduServiceInfoSize; i++) { + ResolveInfo resolveInfo = offHostApduServices.get(i); + ApduServiceInfo apduServiceInfo; + try { + apduServiceInfo = new ApduServiceInfo(packageManager, resolveInfo, false); + } catch (XmlPullParserException | IOException e) { + Log.e(LOG_TAG, "Error creating the apduserviceinfo.", e); + continue; + } + nfcServices.add(apduServiceInfo); + } + return nfcServices; + } + + @Nullable + private Pair<Drawable, CharSequence> getNonPaymentServiceBannerAndLabelIfExists( + @NonNull List<ApduServiceInfo> apduServiceInfos, @NonNull UserHandle user, + @NonNull Context context) { + Context userContext = UserUtils.getUserContext(context, user); + PackageManager userPackageManager = userContext.getPackageManager(); + Pair<Drawable, CharSequence> bannerAndLabel; + int apduServiceInfoSize = apduServiceInfos.size(); + for (int i = 0; i < apduServiceInfoSize; i++) { + ApduServiceInfo serviceInfo = apduServiceInfos.get(i); + if (serviceInfo.getAids().isEmpty()) { + bannerAndLabel = loadBannerAndLabel(serviceInfo, userPackageManager); + if (bannerAndLabel != null) { + return bannerAndLabel; + } + } else { + List<String> aids = serviceInfo.getAids(); + int aidsSize = aids.size(); + for (int j = 0; j < aidsSize; j++) { + String aid = aids.get(j); + String category = serviceInfo.getCategoryForAid(aid); + if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { + bannerAndLabel = loadBannerAndLabel(serviceInfo, userPackageManager); + if (bannerAndLabel != null) { + return bannerAndLabel; + } + } + } + } + } + return null; + } + + @Nullable + private Pair<Drawable, CharSequence> loadBannerAndLabel(@NonNull ApduServiceInfo info, + @NonNull PackageManager userPackageManager) { + Drawable drawable = info.loadBanner(userPackageManager); + CharSequence label = info.loadLabel(userPackageManager); + if (drawable != null && !TextUtils.isEmpty(label)) { + return new Pair<>(drawable, label); + } else { + return null; + } + } + + private static boolean isSystemApplication(@NonNull ApplicationInfo applicationInfo) { + return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java index d9ef047d6..67f04051c 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java @@ -17,14 +17,15 @@ package com.android.permissioncontroller.role.ui.handheld; import android.content.Context; +import android.content.Intent; import android.util.AttributeSet; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceViewHolder; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; import com.android.settingslib.widget.SelectorWithWidgetPreference; /** @@ -33,8 +34,8 @@ import com.android.settingslib.widget.SelectorWithWidgetPreference; public class HandheldRadioPreference extends SelectorWithWidgetPreference implements RoleApplicationPreference { - private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public HandheldRadioPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) { @@ -55,16 +56,15 @@ public class HandheldRadioPreference extends SelectorWithWidgetPreference implem } @Override - public void setUserRestriction( - @Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setRestrictionIntent(@Nullable Intent restrictionIntent) { + mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @Override - public void onBindViewHolder(PreferenceViewHolder holder) { + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @NonNull diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java index 978fe7d5a..3d09f0b46 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui.handheld; import android.content.Context; +import android.content.Intent; import android.util.AttributeSet; import android.view.View; @@ -28,8 +29,8 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.permissioncontroller.R; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RolePreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; import com.android.settingslib.widget.TwoTargetPreference; /** @@ -40,8 +41,8 @@ import com.android.settingslib.widget.TwoTargetPreference; // Made public for com.android.permissioncontroller.role.ui.specialappaccess.handheld public class HandheldRolePreference extends TwoTargetPreference implements RolePreference { - private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); @Nullable private OnSecondTargetClickListener mOnSecondTargetClickListener; @@ -93,8 +94,8 @@ public class HandheldRolePreference extends TwoTargetPreference implements RoleP } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setRestrictionIntent(@Nullable Intent restrictionIntent) { + mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @Override @@ -113,9 +114,10 @@ public class HandheldRolePreference extends TwoTargetPreference implements RoleP // Make the settings button enabled even if the preference itself is disabled. settingsButton.setEnabled(true); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } + @NonNull @Override public HandheldRolePreference asPreference() { return this; diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java index b95440bbd..4b397343c 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessChildFragment.java @@ -164,6 +164,9 @@ public class SpecialAppAccessChildFragment<PF extends PreferenceFragmentCompat preference.setChecked(isHolderPackage); UserHandle user = UserHandle.getUserHandleForUid(qualifyingApplicationInfo.uid); + roleApplicationPreference.setRestrictionIntent( + mRole.getApplicationRestrictionIntentAsUser(qualifyingApplicationInfo, user, + context)); RoleUiBehaviorUtils.prepareApplicationPreferenceAsUser(mRole, roleApplicationPreference, qualifyingApplicationInfo, user, context); preferenceScreen.addPreference(preference); diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java index 4b256cef0..cacb4377f 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/SpecialAppAccessListChildFragment.java @@ -115,9 +115,11 @@ public class SpecialAppAccessListChildFragment<PF extends PreferenceFragmentComp } else { preference = rolePreference.asPreference(); } - RoleUiBehaviorUtils.preparePreferenceAsUser(role, rolePreference, - Process.myUserHandle(), - context); + + rolePreference.setRestrictionIntent(role.getRestrictionIntentAsUser( + Process.myUserHandle(), context)); + RoleUiBehaviorUtils.preparePreferenceAsUser(role, roleItem.getHolderApplicationInfos(), + rolePreference, Process.myUserHandle(), context); preferenceScreen.addPreference(preference); } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java index 1b4dd78a4..ded6d5cb5 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui.specialappaccess.handheld; import android.content.Context; +import android.content.Intent; import android.util.AttributeSet; import androidx.annotation.AttrRes; @@ -25,16 +26,16 @@ import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.preference.PreferenceViewHolder; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; import com.android.settingslib.widget.AppSwitchPreference; /** {@link AppSwitchPreference} that is a role application preference. */ public class HandheldSwitchPreference extends AppSwitchPreference implements RoleApplicationPreference { - private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public HandheldSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { @@ -55,15 +56,15 @@ public class HandheldSwitchPreference extends AppSwitchPreference } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setRestrictionIntent(@Nullable Intent restrictionIntent) { + mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @Override - public void onBindViewHolder(PreferenceViewHolder holder) { + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @NonNull diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/v35/ChangeDefaultCardEmulationActivity.java b/PermissionController/src/com/android/permissioncontroller/role/ui/v35/ChangeDefaultCardEmulationActivity.java new file mode 100644 index 000000000..e1f92e2d3 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/v35/ChangeDefaultCardEmulationActivity.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.role.ui.v35; + +import android.app.Activity; +import android.app.role.RoleManager; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.nfc.cardemulation.CardEmulation; +import android.os.Bundle; +import android.os.Process; +import android.permission.flags.Flags; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.modules.utils.build.SdkLevel; +import com.android.permissioncontroller.role.ui.DefaultAppActivity; + +import java.util.List; +import java.util.Objects; + +/** + * Activity to handle {@link android.nfc.cardemulation.CardEmulation#ACTION_CHANGE_DEFAULT}. + */ +public class ChangeDefaultCardEmulationActivity extends Activity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent; + if (SdkLevel.isAtLeastV() && Flags.walletRoleEnabled()) { + intent = DefaultAppActivity.createIntent(RoleManager.ROLE_WALLET, + Process.myUserHandle(), this); + } else { + intent = getIntent(); + setDefaultPaymentChangeHandlerDialogComponent(intent); + } + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + startActivity(intent); + finish(); + } + + // The only other handler of this intent is in the NFC stack. + private void setDefaultPaymentChangeHandlerDialogComponent(@NonNull Intent intent) { + Intent queryIntent = new Intent(CardEmulation.ACTION_CHANGE_DEFAULT); + PackageManager packageManager = getPackageManager(); + List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(queryIntent, + PackageManager.MATCH_SYSTEM_ONLY); + int resolveInfosSize = resolveInfos.size(); + for (int i = 0; i < resolveInfosSize; i++) { + ResolveInfo resolveInfo = resolveInfos.get(i); + String packageName = resolveInfo.activityInfo.packageName; + if (!Objects.equals(packageName, getPackageName())) { + intent.setClassName(packageName, + resolveInfo.activityInfo.name); + return; + } + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppFragment.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppFragment.kt index 51eb7d40d..156656e33 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppFragment.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.platform.ComposeView import androidx.core.os.BundleCompat import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import com.android.permissioncontroller.permission.ui.wear.setContent +import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme import com.android.permissioncontroller.role.ui.DefaultAppViewModel import com.android.permissioncontroller.role.ui.ManageRoleHolderStateLiveData import com.android.permissioncontroller.role.ui.wear.model.DefaultAppConfirmDialogViewModel @@ -75,9 +75,17 @@ class WearDefaultAppFragment : Fragment() { return ComposeView(activity).apply { setContent { - WearDefaultAppScreen( - WearDefaultAppHelper(activity, user, role, viewModel, confirmDialogViewModel) - ) + WearPermissionTheme { + WearDefaultAppScreen( + WearDefaultAppHelper( + activity, + user, + role, + viewModel, + confirmDialogViewModel + ) + ) + } } } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListHelper.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListHelper.kt index 5e8a2f9ad..bbcedea53 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListHelper.kt +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListHelper.kt @@ -61,6 +61,7 @@ class WearDefaultAppListHelper(val context: Context, val user: UserHandle) { .let { RoleUiBehaviorUtils.preparePreferenceAsUser( roleItem.role, + roleItem.holderApplicationInfos, it, user, context diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt index 29f90ddc3..abaa33a56 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt @@ -16,10 +16,8 @@ package com.android.permissioncontroller.role.ui.wear -import android.app.admin.DevicePolicyManager import android.content.Context import android.content.Intent -import android.provider.Settings import androidx.preference.TwoStatePreference import com.android.permissioncontroller.role.ui.RoleApplicationPreference @@ -32,25 +30,15 @@ class WearRoleApplicationPreference( val label: String, val checked: Boolean, val onDefaultCheckChanged: (Boolean) -> Unit = {}, - private var restriction: String? = null + private var restrictionIntent: Intent? = null ) : TwoStatePreference(context), RoleApplicationPreference { fun getOnCheckChanged(): (Boolean) -> Unit = - restriction?.let { - return { _ -> - context.startActivity( - Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS) - .putExtra(DevicePolicyManager.EXTRA_RESTRICTION, restriction) - ) - } - } - ?: onDefaultCheckChanged + restrictionIntent?.let { { _ -> context.startActivity(it) } } ?: onDefaultCheckChanged - override fun setUserRestriction(userRestriction: String?) { - restriction = userRestriction - setEnabled(restriction == null) + override fun setRestrictionIntent(restrictionIntent: Intent?) { + this.restrictionIntent = restrictionIntent + setEnabled(restrictionIntent == null) } - override fun asTwoStatePreference(): TwoStatePreference { - return this - } + override fun asTwoStatePreference(): TwoStatePreference = this } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt index 16d35ed76..43acf4293 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt @@ -16,10 +16,8 @@ package com.android.permissioncontroller.role.ui.wear -import android.app.admin.DevicePolicyManager import android.content.Context import android.content.Intent -import android.provider.Settings import androidx.preference.Preference import com.android.permissioncontroller.role.ui.RolePreference import com.android.permissioncontroller.role.ui.TwoTargetPreference.OnSecondTargetClickListener @@ -30,30 +28,20 @@ class WearRolePreference( context: Context, val label: String, val onDefaultClicked: () -> Unit = {}, - private var restriction: String? = null + private var restrictionIntent: Intent? = null ) : TwoTargetPreference(context), RolePreference { override fun setOnSecondTargetClickListener(listener: OnSecondTargetClickListener?) { // no-op } - override fun setUserRestriction(userRestriction: String?) { - restriction = userRestriction - setEnabled(restriction == null) + override fun setRestrictionIntent(restrictionIntent: Intent?) { + this.restrictionIntent = restrictionIntent + setEnabled(restrictionIntent == null) } - override fun asPreference(): Preference { - return this - } + override fun asPreference(): Preference = this fun getOnClicked(): () -> Unit = - restriction?.let { - return { - context.startActivity( - Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS) - .putExtra(DevicePolicyManager.EXTRA_RESTRICTION, restriction) - ) - } - } - ?: onDefaultClicked + restrictionIntent?.let { { context.startActivity(it) } } ?: onDefaultClicked } diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java index 7ebc1ebd1..c11a74259 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java +++ b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java @@ -20,19 +20,19 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.UserHandle; -import android.os.UserManager; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.modules.utils.build.SdkLevel; +import com.android.permissioncontroller.role.ui.RequestRoleItemView; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; import com.android.permissioncontroller.role.ui.RolePreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreference; import com.android.permissioncontroller.role.ui.behavior.RoleUiBehavior; import com.android.role.controller.model.Role; +import java.util.List; + /** * Utility methods for Role UI behavior */ @@ -62,6 +62,19 @@ public final class RoleUiBehaviorUtils { } /** + * @see RoleUiBehavior#prepareRequestRoleItemViewAsUser + */ + public static void prepareRequestRoleItemViewAsUser(@NonNull Role role, + @NonNull RequestRoleItemView itemView, @NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, @NonNull Context context) { + RoleUiBehavior uiBehavior = getUiBehavior(role); + if (uiBehavior == null) { + return; + } + uiBehavior.prepareRequestRoleItemViewAsUser(role, itemView, applicationInfo, user, context); + } + + /** * @see RoleUiBehavior#getManageIntentAsUser */ @Nullable @@ -78,15 +91,13 @@ public final class RoleUiBehaviorUtils { * @see RoleUiBehavior#preparePreferenceAsUser */ public static void preparePreferenceAsUser(@NonNull Role role, - @NonNull RolePreference preference, @NonNull UserHandle user, - @NonNull Context context) { - prepareUserRestrictionAwarePreferenceAsUser(role, preference, user, context); - + @NonNull List<ApplicationInfo> applicationInfos, @NonNull RolePreference preference, + @NonNull UserHandle user, @NonNull Context context) { RoleUiBehavior uiBehavior = getUiBehavior(role); if (uiBehavior == null) { return; } - uiBehavior.preparePreferenceAsUser(role, preference, user, context); + uiBehavior.preparePreferenceAsUser(role, preference, applicationInfos, user, context); } /** @@ -96,8 +107,6 @@ public final class RoleUiBehaviorUtils { @NonNull RoleApplicationPreference preference, @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user, @NonNull Context context) { - prepareUserRestrictionAwarePreferenceAsUser(role, preference, user, context); - RoleUiBehavior uiBehavior = getUiBehavior(role); if (uiBehavior == null) { return; @@ -107,18 +116,6 @@ public final class RoleUiBehaviorUtils { context); } - private static void prepareUserRestrictionAwarePreferenceAsUser(@NonNull Role role, - @NonNull UserRestrictionAwarePreference preference, @NonNull UserHandle user, - @NonNull Context context) { - if (SdkLevel.isAtLeastU() && role.isExclusive()) { - UserManager userManager = context.getSystemService(UserManager.class); - boolean hasDisallowConfigDefaultApps = userManager.hasUserRestrictionForUser( - UserManager.DISALLOW_CONFIG_DEFAULT_APPS, user); - preference.setUserRestriction(hasDisallowConfigDefaultApps - ? UserManager.DISALLOW_CONFIG_DEFAULT_APPS : null); - } - } - /** * @see RoleUiBehavior#getConfirmationMessage */ diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/UiUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/UiUtils.java index e13e55c51..4d3320667 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/utils/UiUtils.java +++ b/PermissionController/src/com/android/permissioncontroller/role/utils/UiUtils.java @@ -18,16 +18,12 @@ package com.android.permissioncontroller.role.utils; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.content.Context; -import android.util.DisplayMetrics; -import android.util.TypedValue; import android.view.View; +import android.view.ViewGroup; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; -import androidx.annotation.Dimension; import androidx.annotation.NonNull; -import androidx.annotation.Px; /** * Utility methods about UI. @@ -37,6 +33,26 @@ public class UiUtils { private UiUtils() {} /** + * Set enabled state on a view and its children recursively. + * + * @see androidx.preference.Preference#setEnabledStateOnViews + * + * @param view the view to be set to enabled or not + * @param enabled whether the view should be enabled + */ + public static void setViewTreeEnabled(@NonNull View view, boolean enabled) { + view.setEnabled(enabled); + if (view instanceof ViewGroup) { + ViewGroup viewGroup = (ViewGroup) view; + int childCount = viewGroup.getChildCount(); + for (int i = 0; i < childCount; ++i) { + View childView = viewGroup.getChildAt(i); + setViewTreeEnabled(childView, enabled); + } + } + } + + /** * Set whether a view is shown. * * @param view the view to be set to shown or not diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java index e89470ff6..339b2a12a 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java +++ b/PermissionController/src/com/android/permissioncontroller/role/utils/UserUtils.java @@ -17,8 +17,6 @@ package com.android.permissioncontroller.role.utils; import android.content.Context; -import android.content.pm.PackageManager; -import android.os.Build; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; @@ -26,6 +24,8 @@ import android.os.UserManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.modules.utils.build.SdkLevel; + import java.util.List; import java.util.Objects; @@ -37,56 +37,47 @@ public class UserUtils { private UserUtils() {} /** - * Check whether a user is a profile. + * Get the work profile of current user, if any. * - * @param user the user to check * @param context the {@code Context} to retrieve system services - * @return whether the user is a profile - */ - public static boolean isProfile(@NonNull UserHandle user, @NonNull Context context) { - return isManagedProfile(user, context) || isCloneProfile(user, context); - } - - /** - * Check whether a user is a managed profile. * - * @param user the user to check - * @param context the {@code Context} to retrieve system services - * @return whether the user is a managed profile + * @return the work profile of current user, or {@code null} if none */ - public static boolean isManagedProfile(@NonNull UserHandle user, @NonNull Context context) { - Context userContext = getUserContext(context, user); - UserManager userUserManager = userContext.getSystemService(UserManager.class); - return userUserManager.isManagedProfile(user.getIdentifier()); - } + @Nullable + public static UserHandle getWorkProfile(@NonNull Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + List<UserHandle> profiles = userManager.getUserProfiles(); + UserHandle user = Process.myUserHandle(); - /** - * Check whether a user is a clone profile. - * - * @param user the user to check - * @param context the {@code Context} to retrieve system services - * @return whether the user is a clone profile - */ - public static boolean isCloneProfile(@NonNull UserHandle user, @NonNull Context context) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { - return false; + int profilesSize = profiles.size(); + for (int i = 0; i < profilesSize; i++) { + UserHandle profile = profiles.get(i); + + if (Objects.equals(profile, user)) { + continue; + } + if (!userManager.isManagedProfile(profile.getIdentifier())) { + continue; + } + return profile; } - Context userContext = getUserContext(context, user); - UserManager userUserManager = userContext.getSystemService(UserManager.class); - return userUserManager.isCloneProfile(); + return null; } /** - * Get the work profile of current user, if any. + * Get the private profile of current user, if any. * * @param context the {@code Context} to retrieve system services * - * @return the work profile of current user, or {@code null} if none + * @return the private profile of current user, or {@code null} if none */ @Nullable - public static UserHandle getWorkProfile(@NonNull Context context) { - UserManager userManager = context.getSystemService(UserManager.class); - List<UserHandle> profiles = userManager.getUserProfiles(); + public static UserHandle getPrivateProfile(@NonNull Context context) { + if (!SdkLevel.isAtLeastV()) { + return null; + } + + List<UserHandle> profiles = context.getSystemService(UserManager.class).getUserProfiles(); UserHandle user = Process.myUserHandle(); int profilesSize = profiles.size(); @@ -96,14 +87,22 @@ public class UserUtils { if (Objects.equals(profile, user)) { continue; } - if (!userManager.isManagedProfile(profile.getIdentifier())) { - continue; + if (isPrivateProfile(profile, context)) { + return profile; } - return profile; } return null; } + private static boolean isPrivateProfile(@NonNull UserHandle userHandle, + @NonNull Context context) { + if (!SdkLevel.isAtLeastV() || !android.os.Flags.allowPrivateProfile()) { + return false; + } + Context userContext = context.createContextAsUser(userHandle, /* flags= */ 0); + return userContext.getSystemService(UserManager.class).isPrivateProfile(); + } + /** * Create a context for a user. * diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/SafetyCenterConstants.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/SafetyCenterConstants.java index cf96967ff..8ca76d006 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/SafetyCenterConstants.java +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/SafetyCenterConstants.java @@ -38,6 +38,9 @@ public class SafetyCenterConstants { /** Suffix used to identify a source in the Safety Center work profile */ public static final String WORK_PROFILE_SUFFIX = "work"; + /** Suffix used to identify a source in the Safety Center private profile */ + public static final String PRIVATE_PROFILE_SUFFIX = "private"; + /** Intent extra representing the preference key of a search result */ public static final String EXTRA_SETTINGS_FRAGMENT_ARGS_KEY = ":settings:fragment_args_key"; diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt index 88dd8a6e3..c5e59d3df 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/service/SafetyCenterSearchIndexablesProvider.kt @@ -22,6 +22,7 @@ import android.content.res.Resources import android.database.Cursor import android.database.MatrixCursor import android.os.Build +import android.os.UserHandle import android.os.UserManager import android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS import android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS @@ -46,6 +47,7 @@ import com.android.modules.utils.build.SdkLevel import com.android.permissioncontroller.R import com.android.permissioncontroller.permission.service.BaseSearchIndexablesProvider import com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PERSONAL_PROFILE_SUFFIX +import com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PRIVATE_PROFILE_SUFFIX import com.android.permissioncontroller.safetycenter.SafetyCenterConstants.WORK_PROFILE_SUFFIX import com.android.permissioncontroller.safetycenter.ui.SafetyCenterUiFlags import com.android.permissioncontroller.safetycenter.ui.model.PrivacyControlsViewModel.Pref @@ -111,7 +113,6 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { val context = requireContext() val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java) ?: return cursor - val userManager = context.getSystemService(UserManager::class.java) ?: return cursor val keysToRemove = mutableSetOf<String>() if (safetyCenterManager.isSafetyCenterEnabled) { @@ -124,7 +125,7 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { keysToRemove, staticEntryGroupsAreRemovable = SdkLevel.isAtLeastU() ) - keepActiveEntriesFromRemoval(safetyCenterManager, userManager, keysToRemove) + keepActiveEntriesFromRemoval(safetyCenterManager, context, keysToRemove) } else { collectAllRemovableKeys( safetyCenterManager, @@ -171,18 +172,19 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { var isPersonalEntryAdded = false var isWorkEntryAdded = false - fun MatrixCursor.addIndexableRow(title: CharSequence, isWorkProfile: Boolean) = + fun MatrixCursor.addIndexableRow(title: CharSequence, profileType: ProfileType) = newRow() .add(COLUMN_RANK, 0) .add(COLUMN_TITLE, title) .add(COLUMN_KEYWORDS, searchTerms?.let { "$title, $it" } ?: title) - .add(COLUMN_KEY, safetySource.id.addSuffix(isWorkProfile)) + .add(COLUMN_KEY, safetySource.id.addSuffix(profileType)) .add(COLUMN_INTENT_ACTION, Intent.ACTION_SAFETY_CENTER) .add(COLUMN_SCREEN_TITLE, screenTitle) if (safetySource.id == BIOMETRIC_SOURCE_ID) { - // correct Biometric Unlock title is only available when - // Biometric SafetySource have sent the data to SafetyCenter + // Correct Biometric Unlock title is only available when Biometric SafetySource have + // sent the data to SafetyCenter. Only the main user and the work profile send data for + // the Biometric Safety Source. context.getSystemService(UserManager::class.java)?.let { userManager -> safetyCenterManager.safetyEntries .associateBy { it.entryId } @@ -191,23 +193,31 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { val isWorkProfile = userManager.isManagedProfile(it.key.userId) if (isWorkProfile) { isWorkEntryAdded = true + addIndexableRow(it.value.title, ProfileType.MANAGED) } else { + addIndexableRow(it.value.title, ProfileType.PRIMARY) isPersonalEntryAdded = true } - addIndexableRow(it.value.title, isWorkProfile) } } } if (!isPersonalEntryAdded) { safetyCenterResourcesApk.getNotEmptyStringOrNull(safetySource.titleResId)?.let { - addIndexableRow(title = it, isWorkProfile = false) + addIndexableRow(title = it, ProfileType.PRIMARY) } } - if (!isWorkEntryAdded && safetySource.profile == SafetySource.PROFILE_ALL) { - safetyCenterResourcesApk.getNotEmptyStringOrNull(safetySource.titleForWorkResId)?.let { - addIndexableRow(title = it, isWorkProfile = true) + if (safetySource.profile == SafetySource.PROFILE_ALL) { + if (!isWorkEntryAdded) { + safetyCenterResourcesApk + .getNotEmptyStringOrNull(safetySource.titleForWorkResId) + ?.let { addIndexableRow(title = it, ProfileType.MANAGED) } + } + if (safetySource.id != BIOMETRIC_SOURCE_ID && isPrivateProfileSupported()) { + safetyCenterResourcesApk + .getNotEmptyStringOrNull(safetySource.titleForPrivateProfileResId) + ?.let { addIndexableRow(title = it, ProfileType.PRIVATE) } } } } @@ -219,8 +229,14 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { null } - private fun String.addSuffix(isWorkProfile: Boolean): String = - "${this}_${if (isWorkProfile) WORK_PROFILE_SUFFIX else PERSONAL_PROFILE_SUFFIX}" + private fun String.addSuffix(profileType: ProfileType): String = + "${this}_${ + when (profileType) { + ProfileType.MANAGED -> WORK_PROFILE_SUFFIX + ProfileType.PRIVATE -> PRIVATE_PROFILE_SUFFIX + ProfileType.PRIMARY -> PERSONAL_PROFILE_SUFFIX + } + }" private val SafetyCenterManager.safetySourcesGroupsWithEntries: Sequence<SafetySourcesGroup> get() = @@ -249,9 +265,12 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { .asSequence() .filter { it.type != SAFETY_SOURCE_TYPE_ISSUE_ONLY } .forEach { safetySource -> - keysToRemove.add(safetySource.id.addSuffix(isWorkProfile = false)) + keysToRemove.add(safetySource.id.addSuffix(ProfileType.PRIMARY)) if (safetySource.profile == SafetySource.PROFILE_ALL) { - keysToRemove.add(safetySource.id.addSuffix(isWorkProfile = true)) + keysToRemove.add(safetySource.id.addSuffix(ProfileType.MANAGED)) + if (isPrivateProfileSupported()) { + keysToRemove.add(safetySource.id.addSuffix(ProfileType.PRIVATE)) + } } } } @@ -259,7 +278,7 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { private fun keepActiveEntriesFromRemoval( safetyCenterManager: SafetyCenterManager, - userManager: UserManager, + context: Context, keysToRemove: MutableSet<String> ) { val safetyCenterData = safetyCenterManager.safetyCenterData @@ -268,9 +287,7 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { if (entryGroup != null && SafetyCenterUiFlags.getShowSubpages()) { keysToRemove.remove(entryGroup.id) } - entryOrGroup.entries.forEach { - keepEntryFromRemoval(it.entryId, userManager, keysToRemove) - } + entryOrGroup.entries.forEach { keepEntryFromRemoval(it.entryId, context, keysToRemove) } } if (!SdkLevel.isAtLeastU()) { return @@ -281,18 +298,25 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { .forEach { staticEntry -> val entryId = SafetyCenterBundles.getStaticEntryId(safetyCenterData, staticEntry) if (entryId != null) { - keepEntryFromRemoval(entryId, userManager, keysToRemove) + keepEntryFromRemoval(entryId, context, keysToRemove) } } } private fun keepEntryFromRemoval( entryId: SafetyCenterEntryId, - userManager: UserManager, + context: Context, keysToRemove: MutableSet<String> ) { - val isWorkProfile = userManager.isManagedProfile(entryId.userId) - keysToRemove.remove(entryId.safetySourceId.addSuffix(isWorkProfile)) + val userContext = context.createContextAsUser(UserHandle.of(entryId.userId), /* flags= */ 0) + val userUserManager = userContext.getSystemService(UserManager::class.java) ?: return + if (userUserManager.isManagedProfile) { + keysToRemove.remove(entryId.safetySourceId.addSuffix(ProfileType.MANAGED)) + } else if (isPrivateProfileSupported() && userUserManager.isPrivateProfile) { + keysToRemove.remove(entryId.safetySourceId.addSuffix(ProfileType.PRIVATE)) + } else { + keysToRemove.remove(entryId.safetySourceId.addSuffix(ProfileType.PRIMARY)) + } } private val SafetyCenterManager.safetyEntriesOrGroups: Sequence<SafetyCenterEntryOrGroup> @@ -308,6 +332,12 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { private val SafetyCenterEntry.entryId: SafetyCenterEntryId get() = SafetyCenterIds.entryIdFromString(id) + private fun isPrivateProfileSupported(): Boolean { + return SdkLevel.isAtLeastV() && + com.android.permission.flags.Flags.privateProfileSupported() && + android.os.Flags.allowPrivateProfile() + } + companion object { private const val BIOMETRIC_SOURCE_ID = "AndroidBiometrics" @@ -339,4 +369,10 @@ class SafetyCenterSearchIndexablesProvider : BaseSearchIndexablesProvider() { return safetyCenterDisabled || subpagesDisabled } } + + enum class ProfileType { + PRIMARY, + MANAGED, + PRIVATE + } } diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterActivity.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterActivity.java index ae67250a5..b873bc114 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterActivity.java +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterActivity.java @@ -26,6 +26,7 @@ import static com.android.permissioncontroller.PermissionControllerStatsLog.PRIV import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.EXTRA_SETTINGS_FRAGMENT_ARGS_KEY; import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PERSONAL_PROFILE_SUFFIX; import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PRIVACY_SOURCES_GROUP_ID; +import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PRIVATE_PROFILE_SUFFIX; import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.WORK_PROFILE_SUFFIX; import android.app.ActionBar; @@ -271,6 +272,8 @@ public final class SafetyCenterActivity extends CollapsingToolbarBaseActivity { splitKey = preferenceKey.split("_" + PERSONAL_PROFILE_SUFFIX); } else if (preferenceKey.endsWith(WORK_PROFILE_SUFFIX)) { splitKey = preferenceKey.split("_" + WORK_PROFILE_SUFFIX); + } else if (preferenceKey.endsWith(PRIVATE_PROFILE_SUFFIX)) { + splitKey = preferenceKey.split("_" + PRIVATE_PROFILE_SUFFIX); } else { return ""; } diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt index 6f146e48c..9feecf5d4 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt @@ -92,7 +92,7 @@ abstract class SafetyCenterFragment : PreferenceFragmentCompat() { } val safetyCenterIntent: ParsedSafetyCenterIntent = - requireActivity().getIntent().toSafetyCenterIntent() + requireActivity().intent.toSafetyCenterIntent() val isQsFragment = getArguments()?.getBoolean(QUICK_SETTINGS_SAFETY_CENTER_FRAGMENT, false) ?: false collapsableIssuesCardHelper = @@ -120,7 +120,7 @@ abstract class SafetyCenterFragment : PreferenceFragmentCompat() { override fun onStart() { super.onStart() configureInteractionLogger() - safetyCenterViewModel.interactionLogger.record(Action.SAFETY_CENTER_VIEWED) + logSafetyCenterViewedEvent() } override fun onResume() { @@ -162,6 +162,26 @@ abstract class SafetyCenterFragment : PreferenceFragmentCompat() { abstract fun configureInteractionLogger() + private fun logSafetyCenterViewedEvent() { + // If Safety Center was opened due to an associated notification click (i.e. intent has an + // associated issue), record that issue's metadata on the SAFETY_CENTER_VIEWED event + val maybeIssueKey = requireActivity().intent.toSafetyCenterIntent().safetyCenterIssueKey + val maybeIssue = + maybeIssueKey?.let { + safetyCenterViewModel.getCurrentSafetyCenterDataAsUiData().getMatchingIssue(it) + } + + if (maybeIssue == null) { + safetyCenterViewModel.interactionLogger.record(Action.SAFETY_CENTER_VIEWED) + } else { + safetyCenterViewModel.interactionLogger.recordForIssue( + Action.SAFETY_CENTER_VIEWED, + maybeIssue, + isDismissed = false + ) + } + } + private fun displayErrorDetails(errorDetails: SafetyCenterErrorDetails?) { if (errorDetails == null) return Toast.makeText(requireContext(), errorDetails.errorMessage, Toast.LENGTH_LONG).show() diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt index f4761d3a9..b89abde13 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetySubpageEntryPreference.kt @@ -18,6 +18,7 @@ package com.android.permissioncontroller.safetycenter.ui import android.content.Context import android.os.Build +import android.os.UserHandle import android.os.UserManager import android.safetycenter.SafetyCenterEntry import android.safetycenter.SafetyCenterEntry.IconAction.ICON_ACTION_TYPE_GEAR @@ -28,8 +29,10 @@ import android.widget.TextView import androidx.annotation.RequiresApi import androidx.preference.Preference import androidx.preference.PreferenceViewHolder +import com.android.modules.utils.build.SdkLevel import com.android.permissioncontroller.R import com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PERSONAL_PROFILE_SUFFIX +import com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PRIVATE_PROFILE_SUFFIX import com.android.permissioncontroller.safetycenter.SafetyCenterConstants.WORK_PROFILE_SUFFIX import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterViewModel import com.android.permissioncontroller.safetycenter.ui.view.SafetyEntryCommonViewsManager.Companion.changeEnabledState @@ -93,10 +96,21 @@ class SafetySubpageEntryPreference( private fun setupPreferenceKey() { val entryId: SafetyCenterEntryId = SafetyCenterIds.entryIdFromString(entry.id) - val isWorkProfile = - context.getSystemService(UserManager::class.java)!!.isManagedProfile(entryId.userId) - val keySuffix = if (isWorkProfile) WORK_PROFILE_SUFFIX else PERSONAL_PROFILE_SUFFIX - setKey("${entryId.safetySourceId}_$keySuffix") + val userContext = context.createContextAsUser(UserHandle.of(entryId.userId), /* flags= */ 0) + val userUserManager = userContext.getSystemService(UserManager::class.java) ?: return + if (userUserManager.isManagedProfile) { + setKey("${entryId.safetySourceId}_$WORK_PROFILE_SUFFIX") + } else if (isPrivateProfileSupported() && userUserManager.isPrivateProfile) { + setKey("${entryId.safetySourceId}_$PRIVATE_PROFILE_SUFFIX") + } else { + setKey("${entryId.safetySourceId}_$PERSONAL_PROFILE_SUFFIX") + } + } + + private fun isPrivateProfileSupported(): Boolean { + return SdkLevel.isAtLeastV() && + com.android.permission.flags.Flags.privateProfileSupported() && + android.os.Flags.allowPrivateProfile() } override fun onBindViewHolder(holder: PreferenceViewHolder) { diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java index 8864da07b..87d8744a8 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/StaticSafetyEntryPreference.java @@ -19,9 +19,11 @@ package com.android.permissioncontroller.safetycenter.ui; import static android.os.Build.VERSION_CODES.TIRAMISU; import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PERSONAL_PROFILE_SUFFIX; +import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.PRIVATE_PROFILE_SUFFIX; import static com.android.permissioncontroller.safetycenter.SafetyCenterConstants.WORK_PROFILE_SUFFIX; import android.content.Context; +import android.os.UserHandle; import android.os.UserManager; import android.safetycenter.SafetyCenterStaticEntry; import android.text.TextUtils; @@ -31,6 +33,7 @@ import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.preference.Preference; +import com.android.modules.utils.build.SdkLevel; import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterViewModel; import com.android.safetycenter.internaldata.SafetyCenterEntryId; @@ -81,17 +84,24 @@ public class StaticSafetyEntryPreference extends Preference implements Comparabl } private void setupPreferenceKey(SafetyCenterEntryId entryId) { - boolean isWorkProfile = - getContext() - .getSystemService(UserManager.class) - .isManagedProfile(entryId.getUserId()); - if (isWorkProfile) { + Context userContext = getContext() + .createContextAsUser(UserHandle.of(entryId.getUserId()), /* flags= */ 0); + UserManager userUserManager = userContext.getSystemService(UserManager.class); + if (userUserManager.isManagedProfile()) { setKey(String.format("%s_%s", entryId.getSafetySourceId(), WORK_PROFILE_SUFFIX)); + } else if (isPrivateProfileSupported() && userUserManager.isPrivateProfile()) { + setKey(String.format("%s_%s", entryId.getSafetySourceId(), PRIVATE_PROFILE_SUFFIX)); } else { setKey(String.format("%s_%s", entryId.getSafetySourceId(), PERSONAL_PROFILE_SUFFIX)); } } + private Boolean isPrivateProfileSupported() { + return SdkLevel.isAtLeastV() + && com.android.permission.flags.Flags.privateProfileSupported() + && android.os.Flags.allowPrivateProfile(); + } + @Override public boolean isSameItem(Preference preference) { return preference instanceof StaticSafetyEntryPreference diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt index 239f9a377..69a315f08 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt @@ -16,6 +16,7 @@ package com.android.permissioncontroller.safetycenter.ui.model +import android.os.Build.VERSION_CODES.TIRAMISU import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE import android.safetycenter.SafetyCenterData import android.safetycenter.SafetyCenterEntryGroup @@ -24,12 +25,21 @@ import android.safetycenter.SafetyCenterIssue import android.safetycenter.SafetyCenterIssue.ISSUE_SEVERITY_LEVEL_OK import androidx.annotation.RequiresApi import com.android.safetycenter.internaldata.SafetyCenterBundles.ISSUES_TO_GROUPS_BUNDLE_KEY +import com.android.safetycenter.internaldata.SafetyCenterIds +import com.android.safetycenter.internaldata.SafetyCenterIssueKey /** UI model representation of Safety Center Data */ data class SafetyCenterUiData( val safetyCenterData: SafetyCenterData, val resolvedIssues: Map<IssueId, ActionId> = emptyMap() ) { + @RequiresApi(TIRAMISU) + fun getMatchingIssue(issueKey: SafetyCenterIssueKey): SafetyCenterIssue? { + return safetyCenterData.issues.find { + SafetyCenterIds.issueIdFromString(it.id).safetyCenterIssueKey == issueKey + } + } + /** Returns the [SafetyCenterEntryGroup] corresponding to the provided ID */ @RequiresApi(UPSIDE_DOWN_CAKE) fun getMatchingGroup(groupId: String): SafetyCenterEntryGroup? { diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/MoreIssuesHeaderView.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/MoreIssuesHeaderView.kt index 7b95c3609..ebfbef714 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/MoreIssuesHeaderView.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/view/MoreIssuesHeaderView.kt @@ -45,13 +45,9 @@ constructor( private val moreIssuesCardAnimator = MoreIssuesCardAnimator() private val statusIconView: ImageView by lazyView(R.id.status_icon) private val titleView: TextView by lazyView(R.id.title) - private val expandCollapseLayout: View by lazyView(android.R.id.widget_frame) - private val counterView: TextView by lazyView { - expandCollapseLayout.requireViewById(R.id.widget_title) - } - private val expandCollapseIcon: ImageView by lazyView { - expandCollapseLayout.requireViewById(R.id.widget_icon) - } + private val expandCollapseLayout: View by lazyView(R.id.widget_frame) + private val counterView: TextView by lazyView(R.id.widget_title) + private val expandCollapseIcon: ImageView by lazyView(R.id.widget_icon) private var cornerAnimator: ValueAnimator? = null fun showExpandableHeader( diff --git a/PermissionController/src/com/android/permissioncontroller/user/data/repository/UserRepository.kt b/PermissionController/src/com/android/permissioncontroller/user/data/repository/UserRepository.kt new file mode 100644 index 000000000..fabeb76da --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/user/data/repository/UserRepository.kt @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.user.data.repository + +import android.app.Application +import android.content.pm.UserProperties +import android.os.Build +import android.os.UserHandle +import android.os.UserManager +import androidx.annotation.RequiresApi +import kotlin.concurrent.Volatile +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** This repository encapsulate user and user profiles data exposed by [UserManager]. */ +interface UserRepository { + /** + * Returns a list of UserHandles for profiles associated with the context user, including the + * user itself. + * + * <p>Note that this includes all profile types (not including Restricted profiles). + */ + suspend fun getUserProfilesIncludingCurrentUser(): List<Int> + + /** + * Returns whether a user should be shown in the Settings and sharing surfaces depending on the + * quiet mode. This is only applicable to profile users since the quiet mode concept is only + * applicable to profile users. + */ + suspend fun shouldShowInQuietMode(userId: Int): Boolean + + /** + * Returns whether the given profile is in quiet mode or not. Notes: Quiet mode is only + * supported for managed profiles. + */ + suspend fun isQuietModeEnabled(userId: Int): Boolean + + companion object { + @Volatile private var instance: UserRepository? = null + + fun getInstance(application: Application): UserRepository = + instance + ?: synchronized(this) { UserRepositoryImpl(application).also { instance = it } } + } +} + +class UserRepositoryImpl( + application: Application, + private val dispatcher: CoroutineDispatcher = Dispatchers.Default, +) : UserRepository { + private val userManager = application.getSystemService(UserManager::class.java)!! + + override suspend fun getUserProfilesIncludingCurrentUser(): List<Int> = + withContext(dispatcher) { userManager.userProfiles.map { it.identifier } } + + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + override suspend fun shouldShowInQuietMode(userId: Int): Boolean = + withContext(dispatcher) { + val quiteMode = userManager.getUserProperties(UserHandle.of(userId)).showInQuietMode + quiteMode != UserProperties.SHOW_IN_QUIET_MODE_HIDDEN + } + + override suspend fun isQuietModeEnabled(userId: Int): Boolean = + withContext(dispatcher) { userManager.isQuietModeEnabled(UserHandle.of(userId)) } +} diff --git a/PermissionController/tests/inprocess/src/com/android/permissioncontroller/permission/util/PermissionMappingTest.kt b/PermissionController/tests/inprocess/src/com/android/permissioncontroller/permission/util/PermissionMappingTest.kt index 4d942f815..aa7d7da60 100644 --- a/PermissionController/tests/inprocess/src/com/android/permissioncontroller/permission/util/PermissionMappingTest.kt +++ b/PermissionController/tests/inprocess/src/com/android/permissioncontroller/permission/util/PermissionMappingTest.kt @@ -58,6 +58,16 @@ class PermissionMappingTest { } @Test + fun testGetPlatformPermissionGroupForOp_InvalidOpName() { + try { + assertThat(PermissionMapping.getPlatformPermissionGroupForOp("invalid_opName")) + .isEqualTo(null) + } catch (e: IllegalArgumentException) { + // ignore wtf may throw in some configuration. + } + } + + @Test fun testGetPlatformPermissionGroupForOp_readContacts() { assertThat( PermissionMapping.getPlatformPermissionGroupForOp(AppOpsManager.OPSTR_READ_CONTACTS) diff --git a/PermissionController/tests/mocking/Android.bp b/PermissionController/tests/mocking/Android.bp index 837b055a8..2375a74e6 100644 --- a/PermissionController/tests/mocking/Android.bp +++ b/PermissionController/tests/mocking/Android.bp @@ -117,8 +117,10 @@ android_test { "safety-label", "role-controller", "lottie", - "permissions-flags-lib", + "permissions-aconfig-flags-lib", "android.permission.flags-aconfig-java", + "platform-test-annotations", + "flag-junit", "androidx.test.rules", "androidx.test.ext.truth", diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/appops/data/repository/AppOpRepositoryTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/appops/data/repository/AppOpRepositoryTest.kt new file mode 100644 index 000000000..fdfe2aa08 --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/appops/data/repository/AppOpRepositoryTest.kt @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.appops.data.repository + +import android.app.AppOpsManager +import android.app.AppOpsManager.PackageOps +import android.content.Context +import android.content.pm.PackageManager +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.dx.mockito.inline.extended.ExtendedMockito +import com.android.permissioncontroller.PermissionControllerApplication +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel.AppOpUsageModel +import com.android.permissioncontroller.appops.data.repository.AppOpRepository +import com.android.permissioncontroller.appops.data.repository.AppOpRepositoryImpl +import com.android.permissioncontroller.permission.data.repository.PermissionRepository +import com.android.permissioncontroller.tests.mocking.utils.MockUtil.createMockPackageOps +import com.android.permissioncontroller.tests.mocking.utils.MockUtil.createOpEntry +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.any +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations +import org.mockito.MockitoSession +import org.mockito.quality.Strictness + +@RunWith(AndroidJUnit4::class) +class AppOpRepositoryTest { + @Mock private lateinit var application: PermissionControllerApplication + @Mock private lateinit var context: Context + @Mock private lateinit var packageManager: PackageManager + @Mock private lateinit var appOpsManager: AppOpsManager + + private lateinit var underTest: AppOpRepository + private lateinit var mockitoSession: MockitoSession + + private val currentUser = android.os.Process.myUserHandle() + private val testPackageName = "test.package" + private val testAppId = 100203 + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + mockitoSession = + ExtendedMockito.mockitoSession() + .mockStatic(PermissionControllerApplication::class.java) + .strictness(Strictness.LENIENT) + .startMocking() + whenever(PermissionControllerApplication.get()).thenReturn(application) + whenever(application.applicationContext).thenReturn(context) + whenever(application.packageManager).thenReturn(packageManager) + whenever(application.getSystemService(AppOpsManager::class.java)).thenReturn(appOpsManager) + + val permissionRepository = PermissionRepository.getInstance(application) + underTest = AppOpRepositoryImpl(application, permissionRepository) + } + + @After + fun finish() { + mockitoSession.finishMocking() + } + + @Test + fun verifyPackageAppOpsUsageData() = runTest { + val packageOpsData = createPackageOpsMockData() + whenever(appOpsManager.getPackagesForOps(any(Array<String>::class.java))) + .thenReturn(listOf(packageOpsData)) + + val packageOps = underTest.packageAppOpsUsages.take(1).toList().first() + val expectedAppOpUsages = + packageOpsData.ops.map { + AppOpUsageModel(it.opStr, it.getLastAccessTime(OPS_LAST_ACCESS_FLAGS)) + } + assertThat(packageOps.size).isEqualTo(1) + assertThat(packageOps[0].packageName).isEqualTo(testPackageName) + assertThat(packageOps[0].usages).isEqualTo(expectedAppOpUsages) + } + + private fun createPackageOpsMockData(): PackageOps { + val opEntries = + listOf( + createOpEntry(AppOpsManager.OPSTR_FINE_LOCATION, 100), + createOpEntry(AppOpsManager.OPSTR_FINE_LOCATION, 200), + createOpEntry(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 300), + createOpEntry(AppOpsManager.OPSTR_CAMERA, 350), + ) + return createMockPackageOps(testPackageName, opEntries, currentUser.getUid(testAppId)) + } + + companion object { + private const val OPS_LAST_ACCESS_FLAGS = + AppOpsManager.OP_FLAG_SELF or + AppOpsManager.OP_FLAG_TRUSTED_PROXIED or + AppOpsManager.OP_FLAG_TRUSTED_PROXY + } +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/appops/data/repository/FakeAppOpRepository.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/appops/data/repository/FakeAppOpRepository.kt new file mode 100644 index 000000000..326459d4b --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/appops/data/repository/FakeAppOpRepository.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.appops.data.repository + +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel +import com.android.permissioncontroller.appops.data.repository.AppOpRepository +import kotlinx.coroutines.flow.Flow + +class FakeAppOpRepository(override val packageAppOpsUsages: Flow<List<PackageAppOpUsageModel>>) : + AppOpRepository diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/coroutines/Flows.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/coroutines/Flows.kt new file mode 100644 index 000000000..cefaf18a7 --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/coroutines/Flows.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("OPT_IN_USAGE") + +package com.android.permissioncontroller.tests.mocking.coroutines + +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent + +/** + * Collect [flow] in a new [Job] and return a getter for the last collected value. + * + * ``` + * fun myTest() = runTest { + * // ... + * val actual by collectLastValue(underTest.flow) + * assertThat(actual).isEqualTo(expected) + * } + * ``` + */ +fun <T> TestScope.collectLastValue( + flow: Flow<T>, + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, +): FlowValue<T?> { + val values by + collectValues( + flow = flow, + context = context, + start = start, + ) + return FlowValueImpl { values.lastOrNull() } +} + +/** + * Collect [flow] in a new [Job] and return a getter for the collection of values collected. + * + * ``` + * fun myTest() = runTest { + * // ... + * val values by collectValues(underTest.flow) + * assertThat(values).isEqualTo(listOf(expected1, expected2, ...)) + * } + * ``` + */ +fun <T> TestScope.collectValues( + flow: Flow<T>, + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, +): FlowValue<List<T>> { + val values = mutableListOf<T>() + backgroundScope.launch(context, start) { flow.collect(values::add) } + return FlowValueImpl { + runCurrent() + values.toList() + } +} + +/** @see collectLastValue */ +interface FlowValue<T> : ReadOnlyProperty<Any?, T> { + operator fun invoke(): T +} + +private class FlowValueImpl<T>(private val block: () -> T) : FlowValue<T> { + override operator fun invoke(): T = block() + override fun getValue(thisRef: Any?, property: KProperty<*>): T = invoke() +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/data/repository/FakePermissionRepository.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/data/repository/FakePermissionRepository.kt new file mode 100644 index 000000000..8afb3999d --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/data/repository/FakePermissionRepository.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.permission.data.repository + +import android.content.Context +import android.os.UserHandle +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.permission.data.repository.PermissionRepository +import com.android.permissioncontroller.permission.utils.PermissionMapping + +class FakePermissionRepository(private val permissionFlags: Map<String, Int> = emptyMap()) : + PermissionRepository { + override suspend fun getPermissionFlags( + permissionName: String, + packageName: String, + user: UserHandle + ): Int { + return permissionFlags[permissionName] ?: 0 + } + + override suspend fun getPermissionGroupLabel( + context: Context, + groupName: String + ): CharSequence { + TODO("Not yet implemented") + } + + override fun getPermissionGroupsForPrivacyDashboard(): List<String> { + return if (SdkLevel.isAtLeastT()) { + PermissionMapping.getPlatformPermissionGroups().filter { + it != android.Manifest.permission_group.NOTIFICATIONS + } + } else { + PermissionMapping.getPlatformPermissionGroups() + } + } +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionUsageUseCaseTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionUsageUseCaseTest.kt new file mode 100644 index 000000000..8bfecf0fb --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionUsageUseCaseTest.kt @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.permission.domain.usecase + +import android.app.AppOpsManager +import android.content.Context +import android.content.pm.ApplicationInfo +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import android.os.UserHandle +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.dx.mockito.inline.extended.ExtendedMockito +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.PermissionControllerApplication +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel.AppOpUsageModel +import com.android.permissioncontroller.permission.domain.model.PermissionGroupUsageModel +import com.android.permissioncontroller.permission.domain.usecase.GetPermissionGroupUsageUseCase +import com.android.permissioncontroller.permission.utils.Utils +import com.android.permissioncontroller.pm.data.model.PackageInfoModel +import com.android.permissioncontroller.role.data.repository.RoleRepository +import com.android.permissioncontroller.tests.mocking.appops.data.repository.FakeAppOpRepository +import com.android.permissioncontroller.tests.mocking.coroutines.collectLastValue +import com.android.permissioncontroller.tests.mocking.permission.data.repository.FakePermissionRepository +import com.android.permissioncontroller.tests.mocking.pm.data.repository.FakePackageRepository +import com.android.permissioncontroller.tests.mocking.role.data.repository.FakeRoleRepository +import com.android.permissioncontroller.tests.mocking.user.data.repository.FakeUserRepository +import com.android.permissioncontroller.user.data.repository.UserRepository +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Assume +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations +import org.mockito.MockitoSession +import org.mockito.quality.Strictness + +@RunWith(AndroidJUnit4::class) +class GetPermissionUsageUseCaseTest { + @Mock private lateinit var application: PermissionControllerApplication + @Mock private lateinit var context: Context + + private lateinit var mockitoSession: MockitoSession + private lateinit var userRepository: UserRepository + private lateinit var roleRepository: RoleRepository + private lateinit var packageInfos: MutableMap<String, PackageInfoModel> + private val currentUser = android.os.Process.myUserHandle() + private val testPackageName = "test.package" + private val guestUserPkgName = "test.package.guest" + private val exemptedPkgName = "test.exempted.package" + private val guestUser = UserHandle.of(345) + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + mockitoSession = + ExtendedMockito.mockitoSession() + .mockStatic(PermissionControllerApplication::class.java) + .mockStatic(Utils::class.java) + .strictness(Strictness.LENIENT) + .startMocking() + + whenever(PermissionControllerApplication.get()).thenReturn(application) + whenever(application.applicationContext).thenReturn(context) + + userRepository = FakeUserRepository(listOf(currentUser.identifier)) + roleRepository = FakeRoleRepository(setOf(exemptedPkgName)) + packageInfos = + mapOf( + testPackageName to getPackageInfoModel(testPackageName), + guestUserPkgName to getPackageInfoModel(guestUserPkgName), + exemptedPkgName to getPackageInfoModel(exemptedPkgName), + ) + .toMutableMap() + } + + @After + fun finish() { + mockitoSession.finishMocking() + } + + @Test + fun invalidAppOpIsFiltered() = runTest { + val appOpsUsageMillis = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + AppOpUsageModel("OPSTR_INVALID", 100) + ) + val appOpsUsage = + PackageAppOpUsageModel(testPackageName, appOpsUsageMillis, currentUser.identifier) + val appOpsUsageModelFlow = flow { emit(listOf(appOpsUsage)) } + val underTest = getPermissionGroupUsageUseCase(appOpsUsageModelFlow) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo(listOf(PermissionGroupUsageModel(CAMERA_PERMISSION_GROUP, 100, true))) + } + + @Test + fun guestUserUsageIsFiltered() = runTest { + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + ) + val guestAppOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 100), + ) + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + PackageAppOpUsageModel(guestUserPkgName, guestAppOpsUsage, guestUser.identifier) + ) + ) + } + val underTest = getPermissionGroupUsageUseCase(appOpsUsageModelFlow) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo(listOf(PermissionGroupUsageModel(CAMERA_PERMISSION_GROUP, 100, true))) + } + + @Test + fun quiteProfileShowUsageInQuietMode() = runTest { + Assume.assumeTrue(SdkLevel.isAtLeastV()) + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 150), + ) + + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + ) + ) + } + val userRepository = + FakeUserRepository( + currentUserProfiles = listOf(currentUser.identifier), + quietUserProfiles = listOf(currentUser.identifier), + showInQuiteModeProfiles = listOf(currentUser.identifier) + ) + val underTest = + getPermissionGroupUsageUseCase(appOpsUsageModelFlow, userRepo = userRepository) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo( + listOf( + PermissionGroupUsageModel(CAMERA_PERMISSION_GROUP, 100, true), + PermissionGroupUsageModel(MICROPHONE_PERMISSION_GROUP, 150, true) + ) + ) + } + + @Test + fun quietProfileAppOpsUsageIsFiltered() = runTest { + Assume.assumeTrue(SdkLevel.isAtLeastV()) + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + ) + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + ) + ) + } + val userRepository = + FakeUserRepository( + currentUserProfiles = listOf(currentUser.identifier), + quietUserProfiles = listOf(currentUser.identifier), + showInQuiteModeProfiles = emptyList() + ) + val underTest = + getPermissionGroupUsageUseCase(appOpsUsageModelFlow, userRepo = userRepository) + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages).isEmpty() + } + + @Test + fun exemptedPackageIsFiltered() = runTest { + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + ) + val exemptedOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 100), + ) + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + PackageAppOpUsageModel( + exemptedPkgName, + exemptedOpsUsage, + currentUser.identifier + ) + ) + ) + } + val underTest = getPermissionGroupUsageUseCase(appOpsUsageModelFlow) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo(listOf(PermissionGroupUsageModel(CAMERA_PERMISSION_GROUP, 100, true))) + } + + @Test + fun permissionNoLongerRequestedOpsAreFiltered() = runTest { + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 100), + ) + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + ) + ) + } + packageInfos[testPackageName] = + getPackageInfoModel( + testPackageName, + requestedPermissions = listOf(RECORD_AUDIO_PERMISSION) + ) + val underTest = getPermissionGroupUsageUseCase(appOpsUsageModelFlow) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo(listOf(PermissionGroupUsageModel(MICROPHONE_PERMISSION_GROUP, 100, true))) + } + + @Test + fun mostRecentAccessedTimestampIsShown() = runTest { + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 150), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 100), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 80), + ) + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + ) + ) + } + val underTest = getPermissionGroupUsageUseCase(appOpsUsageModelFlow) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo( + listOf( + PermissionGroupUsageModel(CAMERA_PERMISSION_GROUP, 150, true), + PermissionGroupUsageModel(MICROPHONE_PERMISSION_GROUP, 100, true) + ) + ) + } + + @Test + fun nonSystemAppsUsageIsUserSensitive() = runTest { + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 100), + ) + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + ) + ) + } + // test package is not a system package + val underTest = getPermissionGroupUsageUseCase(appOpsUsageModelFlow) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo( + listOf( + PermissionGroupUsageModel(CAMERA_PERMISSION_GROUP, 100, true), + PermissionGroupUsageModel(MICROPHONE_PERMISSION_GROUP, 100, true) + ) + ) + } + + @Test + fun systemAppsUsageIsUserSensitive() = runTest { + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, 100), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, 100), + ) + val appOpsUsageModelFlow = flow { + emit( + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + ) + ) + } + val permissionFlags = + mapOf<String, Int>( + CAMERA_PERMISSION to PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, + RECORD_AUDIO_PERMISSION to 0, // not user sensitive when granted + ) + packageInfos[testPackageName] = + getPackageInfoModel( + testPackageName, + requestedPermissions = listOf(CAMERA_PERMISSION, RECORD_AUDIO_PERMISSION), + permissionsFlags = + listOf( + PackageInfo.REQUESTED_PERMISSION_GRANTED, + PackageInfo.REQUESTED_PERMISSION_GRANTED + ), + applicationFlags = ApplicationInfo.FLAG_SYSTEM + ) + val underTest = + getPermissionGroupUsageUseCase(appOpsUsageModelFlow, permissionFlags = permissionFlags) + + val permissionGroupUsages by collectLastValue(underTest()) + assertThat(permissionGroupUsages) + .isEqualTo( + listOf( + PermissionGroupUsageModel(CAMERA_PERMISSION_GROUP, 100, true), + PermissionGroupUsageModel(MICROPHONE_PERMISSION_GROUP, 100, false) + ) + ) + } + + private fun getPackageInfoModel( + packageName: String, + requestedPermissions: List<String> = listOf(CAMERA_PERMISSION, RECORD_AUDIO_PERMISSION), + permissionsFlags: List<Int> = listOf(0, 0), + applicationFlags: Int = 0, + ) = PackageInfoModel(packageName, requestedPermissions, permissionsFlags, applicationFlags) + + private fun getPermissionGroupUsageUseCase( + packageAppOpsUsages: Flow<List<PackageAppOpUsageModel>>, + permissionFlags: Map<String, Int> = emptyMap(), + userRepo: UserRepository = userRepository + ): GetPermissionGroupUsageUseCase { + val permissionRepository = FakePermissionRepository(permissionFlags) + val packageRepository = FakePackageRepository(packageInfos) + val appOpUsageRepository = FakeAppOpRepository(packageAppOpsUsages) + return GetPermissionGroupUsageUseCase( + packageRepository, + permissionRepository, + appOpUsageRepository, + roleRepository, + userRepo + ) + } + + companion object { + private val CAMERA_PERMISSION = android.Manifest.permission.CAMERA + private val RECORD_AUDIO_PERMISSION = android.Manifest.permission.RECORD_AUDIO + private val CAMERA_PERMISSION_GROUP = android.Manifest.permission_group.CAMERA + private val MICROPHONE_PERMISSION_GROUP = android.Manifest.permission_group.MICROPHONE + } +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/ui/model/PermissionUsageViewModelTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/ui/model/PermissionUsageViewModelTest.kt new file mode 100644 index 000000000..6d83963d1 --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/ui/model/PermissionUsageViewModelTest.kt @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.permission.ui.model + +import android.app.AppOpsManager +import android.content.Context +import android.content.pm.ApplicationInfo +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.dx.mockito.inline.extended.ExtendedMockito +import com.android.permissioncontroller.PermissionControllerApplication +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel +import com.android.permissioncontroller.appops.data.model.PackageAppOpUsageModel.AppOpUsageModel +import com.android.permissioncontroller.permission.data.repository.PermissionRepository +import com.android.permissioncontroller.permission.domain.usecase.GetPermissionGroupUsageUseCase +import com.android.permissioncontroller.permission.ui.viewmodel.PermissionUsageViewModelV2 +import com.android.permissioncontroller.permission.utils.PermissionMapping +import com.android.permissioncontroller.pm.data.model.PackageInfoModel +import com.android.permissioncontroller.tests.mocking.appops.data.repository.FakeAppOpRepository +import com.android.permissioncontroller.tests.mocking.coroutines.collectLastValue +import com.android.permissioncontroller.tests.mocking.permission.data.repository.FakePermissionRepository +import com.android.permissioncontroller.tests.mocking.pm.data.repository.FakePackageRepository +import com.android.permissioncontroller.tests.mocking.role.data.repository.FakeRoleRepository +import com.android.permissioncontroller.tests.mocking.user.data.repository.FakeUserRepository +import com.google.common.truth.Truth.assertThat +import java.util.concurrent.TimeUnit +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations +import org.mockito.MockitoSession +import org.mockito.quality.Strictness + +@RunWith(AndroidJUnit4::class) +class PermissionUsageViewModelTest { + @Mock private lateinit var application: PermissionControllerApplication + @Mock private lateinit var context: Context + private lateinit var mockitoSession: MockitoSession + + private lateinit var permissionRepository: PermissionRepository + private val currentUser = android.os.Process.myUserHandle() + private val testPackageName = "test.package" + private val systemPackageName = "test.package.system" + private lateinit var packageInfos: MutableMap<String, PackageInfoModel> + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + mockitoSession = + ExtendedMockito.mockitoSession() + .mockStatic(PermissionControllerApplication::class.java) + .strictness(Strictness.LENIENT) + .startMocking() + + whenever(PermissionControllerApplication.get()).thenReturn(application) + whenever(application.applicationContext).thenReturn(context) + PermissionMapping.addHealthPermissionsToPlatform(setOf("health1")) + + val permissionFlags = + mapOf<String, Int>( + CAMERA_PERMISSION to PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, + RECORD_AUDIO_PERMISSION to 0, // not user sensitive + ) + permissionRepository = FakePermissionRepository(permissionFlags) + packageInfos = + mapOf( + testPackageName to getPackageInfoModel(testPackageName), + systemPackageName to + getPackageInfoModel( + systemPackageName, + applicationFlags = ApplicationInfo.FLAG_SYSTEM + ), + ) + .toMutableMap() + } + + @After + fun finish() { + mockitoSession.finishMocking() + } + + @Test + fun allPermissionGroupsAreShown() = runTest { + val permissionUsageViewModel = + PermissionUsageViewModelV2( + application, + permissionRepository, + getPermissionGroupUsageUseCase(), + backgroundScope + ) + val uiData = + checkNotNull( + collectLastValue(permissionUsageViewModel.getPermissionUsagesUiDataFlow()).invoke() + ) + assertThat(uiData.permissionGroupUsageCount.size).isEqualTo(15) + } + + @Test + fun permissionGroupsCountNonSystemApps() = runTest { + val timestamp = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(5) + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, timestamp), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, timestamp), + ) + val appOpsUsageModels = + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + PackageAppOpUsageModel(systemPackageName, appOpsUsage, currentUser.identifier), + ) + val permissionUsageUseCase = getPermissionGroupUsageUseCase(appOpsUsageModels) + val permissionUsageViewModel = + PermissionUsageViewModelV2( + application, + permissionRepository, + permissionUsageUseCase, + backgroundScope + ) + val uiData = + checkNotNull( + collectLastValue(permissionUsageViewModel.getPermissionUsagesUiDataFlow()).invoke() + ) + val permissionGroupsCount = uiData.permissionGroupUsageCount + assertThat(permissionGroupsCount[CAMERA_PERMISSION_GROUP]).isEqualTo(2) + assertThat(permissionGroupsCount[MICROPHONE_PERMISSION_GROUP]).isEqualTo(1) + } + + @Test + fun permissionGroupsCountAllApps() = runTest { + val timestamp = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(5) + val appOpsUsage = + listOf( + AppOpUsageModel(AppOpsManager.OPSTR_CAMERA, timestamp), + AppOpUsageModel(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, timestamp), + ) + val appOpsUsageModels = + listOf( + PackageAppOpUsageModel(testPackageName, appOpsUsage, currentUser.identifier), + PackageAppOpUsageModel(systemPackageName, appOpsUsage, currentUser.identifier), + ) + val permissionUsageUseCase = getPermissionGroupUsageUseCase(appOpsUsageModels) + val permissionUsageViewModel = + PermissionUsageViewModelV2( + application, + permissionRepository, + permissionUsageUseCase, + backgroundScope + ) + + collectLastValue(permissionUsageViewModel.getPermissionUsagesUiDataFlow()).invoke() + val uiData = permissionUsageViewModel.updateShowSystem(true) + val permissionGroupsCount = uiData.permissionGroupUsageCount + assertThat(permissionGroupsCount[CAMERA_PERMISSION_GROUP]).isEqualTo(2) + assertThat(permissionGroupsCount[MICROPHONE_PERMISSION_GROUP]).isEqualTo(2) + } + + private fun getPermissionGroupUsageUseCase( + packageAppOpsUsages: List<PackageAppOpUsageModel> = emptyList(), + ): GetPermissionGroupUsageUseCase { + val userRepository = FakeUserRepository(listOf(currentUser.identifier)) + val roleRepository = FakeRoleRepository() + val packageRepository = FakePackageRepository(packageInfos) + val appOpUsageRepository = FakeAppOpRepository(flowOf(packageAppOpsUsages)) + return GetPermissionGroupUsageUseCase( + packageRepository, + permissionRepository, + appOpUsageRepository, + roleRepository, + userRepository + ) + } + + private fun getPackageInfoModel( + packageName: String, + requestedPermissions: List<String> = listOf(CAMERA_PERMISSION, RECORD_AUDIO_PERMISSION), + permissionsFlags: List<Int> = + listOf( + PackageInfo.REQUESTED_PERMISSION_GRANTED, + PackageInfo.REQUESTED_PERMISSION_GRANTED + ), + applicationFlags: Int = 0, + ) = PackageInfoModel(packageName, requestedPermissions, permissionsFlags, applicationFlags) + + companion object { + private val CAMERA_PERMISSION = android.Manifest.permission.CAMERA + private val RECORD_AUDIO_PERMISSION = android.Manifest.permission.RECORD_AUDIO + private val CAMERA_PERMISSION_GROUP = android.Manifest.permission_group.CAMERA + private val MICROPHONE_PERMISSION_GROUP = android.Manifest.permission_group.MICROPHONE + } +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/pm/data/repository/FakePackageRepository.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/pm/data/repository/FakePackageRepository.kt new file mode 100644 index 000000000..1ef193e98 --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/pm/data/repository/FakePackageRepository.kt @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.pm.data.repository + +import android.os.UserHandle +import com.android.permissioncontroller.pm.data.model.PackageInfoModel +import com.android.permissioncontroller.pm.data.repository.PackageRepository + +class FakePackageRepository(private val packages: Map<String, PackageInfoModel> = emptyMap()) : + PackageRepository { + override suspend fun getPackageInfo( + packageName: String, + user: UserHandle, + flags: Int + ): PackageInfoModel? { + return packages[packageName] + } +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/privacysources/NotificationListenerPrivacySourceTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/privacysources/NotificationListenerPrivacySourceTest.kt index 30f0880e1..cc3b096a8 100644 --- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/privacysources/NotificationListenerPrivacySourceTest.kt +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/privacysources/NotificationListenerPrivacySourceTest.kt @@ -122,14 +122,14 @@ class NotificationListenerPrivacySourceTest { whenever( Utils.getApplicationLabel( any(ContextWrapper::class.java), - eq(packageInfo1.applicationInfo) + eq(packageInfo1.applicationInfo!!) ) ) .thenReturn(testComponent1.className) whenever( Utils.getApplicationLabel( any(ContextWrapper::class.java), - eq(packageInfo2.applicationInfo) + eq(packageInfo2.applicationInfo!!) ) ) .thenReturn(testComponent2.className) diff --git a/flags/java/com/android/permission/flags/PermissionsFlags.java b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/role/data/repository/FakeRoleRepository.kt index afab3fae5..65469ea6f 100644 --- a/flags/java/com/android/permission/flags/PermissionsFlags.java +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/role/data/repository/FakeRoleRepository.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,10 @@ * limitations under the License. */ -package com.android.permission.flags; +package com.android.permissioncontroller.tests.mocking.role.data.repository -/** Class used for flags that do not work with aconfig tooling */ -public final class PermissionsFlags {} +import com.android.permissioncontroller.role.data.repository.RoleRepository + +class FakeRoleRepository(private val exemptedPackages: Set<String> = emptySet()) : RoleRepository { + override suspend fun getExemptedPackages(): Set<String> = exemptedPackages +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/user/data/repository/FakeUserRepository.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/user/data/repository/FakeUserRepository.kt new file mode 100644 index 000000000..7e78742b5 --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/user/data/repository/FakeUserRepository.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.user.data.repository + +import android.os.Process +import com.android.permissioncontroller.user.data.repository.UserRepository + +class FakeUserRepository( + private val currentUserProfiles: List<Int> = listOf(Process.myUserHandle().identifier), + private val quietUserProfiles: List<Int> = emptyList(), + private val showInQuiteModeProfiles: List<Int> = emptyList() +) : UserRepository { + override suspend fun getUserProfilesIncludingCurrentUser(): List<Int> = currentUserProfiles + + override suspend fun shouldShowInQuietMode(userId: Int): Boolean = + showInQuiteModeProfiles.contains(userId) + + override suspend fun isQuietModeEnabled(userId: Int): Boolean = + quietUserProfiles.contains(userId) +} diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/utils/MockUtil.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/utils/MockUtil.kt new file mode 100644 index 000000000..1147bb74e --- /dev/null +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/utils/MockUtil.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.tests.mocking.utils + +import android.app.AppOpsManager +import android.content.pm.ApplicationInfo +import android.content.pm.PackageInfo +import org.mockito.Mockito +import org.mockito.Mockito.`when` as whenever + +object MockUtil { + fun createMockPackageOps( + packageName: String, + ops: List<AppOpsManager.OpEntry>, + uid: Int + ): AppOpsManager.PackageOps { + val pkgOp = Mockito.mock(AppOpsManager.PackageOps::class.java) + whenever(pkgOp.packageName).thenReturn(packageName) + whenever(pkgOp.ops).thenReturn(ops) + whenever(pkgOp.uid).thenReturn(uid) + return pkgOp + } + + fun createOpEntry(opStr: String, time: Long): AppOpsManager.OpEntry { + val opEntry = Mockito.mock(AppOpsManager.OpEntry::class.java) + whenever(opEntry.opStr).thenReturn(opStr) + whenever(opEntry.getLastAccessTime(Mockito.anyInt())).thenReturn(time) + return opEntry + } + + fun createPackageInfo( + testPackageName: String, + requestedPerms: List<String>, + requestedFlags: List<Int>, + applicationInfoFlags: Int = 0 + ): PackageInfo { + val appInfo = ApplicationInfo() + appInfo.flags = applicationInfoFlags + return PackageInfo().apply { + packageName = testPackageName + requestedPermissions = requestedPerms.toTypedArray() + requestedPermissionsFlags = requestedFlags.toIntArray() + applicationInfo = appInfo + } + } +} diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/v31/PermissionUsageFragmentTest.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/v31/PermissionUsageFragmentTest.kt index c7292f3e7..f81b620ce 100644 --- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/v31/PermissionUsageFragmentTest.kt +++ b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/v31/PermissionUsageFragmentTest.kt @@ -44,7 +44,6 @@ class PermissionUsageFragmentTest : PermissionHub2Test() { private val APP = "com.android.permissioncontroller.tests.appthatrequestpermission" private val APP_LABEL = "CameraRequestApp" private val CAMERA_PREF_LABEL = "Camera" - private val REFRESH = "Refresh" @Before fun setup() { @@ -67,14 +66,8 @@ class PermissionUsageFragmentTest : PermissionHub2Test() { } eventually { - try { - waitFindObject(By.res("android:id/title").textContains(CAMERA_PREF_LABEL)).click() - } catch (e: Exception) { - waitFindObject(By.textContains(REFRESH)).click() - throw e - } + waitFindObject(By.res("android:id/title").textContains(CAMERA_PREF_LABEL)).click() } - waitFindObject(By.textContains(APP_LABEL)) } diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearPermissionUsageDetailsFragmentTest.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearPermissionUsageDetailsFragmentTest.kt deleted file mode 100644 index 999c89fc7..000000000 --- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearPermissionUsageDetailsFragmentTest.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.permissioncontroller.permissionui.ui.wear - -import android.Manifest.permission.CAMERA -import android.content.Intent -import android.os.Build -import android.permission.cts.PermissionUtils.grantPermission -import android.permission.cts.PermissionUtils.install -import android.permission.cts.PermissionUtils.uninstallApp -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SdkSuppress -import androidx.test.uiautomator.By -import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity -import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObject -import com.android.permissioncontroller.permissionui.PermissionHub2Test -import com.android.permissioncontroller.permissionui.pressHome -import com.android.permissioncontroller.permissionui.wakeUpScreen -import org.junit.After -import org.junit.Assume.assumeTrue -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith - -/** Tests for [WearPermissionUsageDetailsFragment] */ -@RunWith(AndroidJUnit4::class) -@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) -class WearPermissionUsageDetailsFragmentTest : PermissionHub2Test() { - private val CAMERA_APK = - "/data/local/tmp/pc-permissionui/PermissionUiUseCameraPermissionApp.apk" - private val CAMERA_APP = "com.android.permissioncontroller.tests.appthatrequestpermission" - private val CAMERA_APP_LABEL = "CameraRequestApp" - private val CAMERA_PREF_LABEL = "Camera" - private val MANAGE_PERMISSION_LABEL = "Manage permission" - private val APP_PERMISSIONS_TITLE = "App permissions" - private val TIMEOUT = 30_000L - - @Before - fun setup() { - assumeTrue(isWear()) - wakeUpScreen() - install(CAMERA_APK) - grantPermission(CAMERA_APP, CAMERA) - accessCamera() - goToPermissionUsageDetails() - } - - private fun goToPermissionUsageDetails() { - runWithShellPermissionIdentity { - context.startActivity( - Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - } - - clickObject(CAMERA_PREF_LABEL) - } - - @Test - fun testClickAppThenTransitToAppPermissionGroups() { - clickObject(CAMERA_APP_LABEL) - - // Find the title of AppPermissionGroups. - waitFindObject(By.textContains(APP_PERMISSIONS_TITLE), TIMEOUT) - // Find the permission in the list. - waitFindObject(By.textContains(CAMERA_PREF_LABEL), TIMEOUT) - } - - @Test - fun testClickManagePermissionThenTransitToPermissionApps() { - clickObject(MANAGE_PERMISSION_LABEL) - - // Find the title of PermissionApps. - waitFindObject(By.textContains(CAMERA_PREF_LABEL), TIMEOUT) - // Find the test app is in the app list. - waitFindObject(By.textContains(CAMERA_APP_LABEL), TIMEOUT) - } - - @After - fun tearDown() { - uninstallApp(CAMERA_APP) - pressHome() - } -} diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearPermissionUsageFragmentTest.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearPermissionUsageFragmentTest.kt deleted file mode 100644 index e37b97874..000000000 --- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearPermissionUsageFragmentTest.kt +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.permissioncontroller.permissionui.ui.wear - -import android.Manifest.permission.CAMERA -import android.Manifest.permission.READ_CALENDAR -import android.app.AppOpsManager -import android.content.Intent -import android.content.pm.PackageManager -import android.os.Build -import android.os.Process -import android.permission.cts.PermissionUtils.grantPermission -import android.permission.cts.PermissionUtils.install -import android.permission.cts.PermissionUtils.uninstallApp -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.SdkSuppress -import androidx.test.uiautomator.By -import com.android.compatibility.common.util.SystemUtil.eventually -import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity -import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObject -import com.android.permissioncontroller.permissionui.PermissionHub2Test -import com.android.permissioncontroller.permissionui.pressHome -import com.android.permissioncontroller.permissionui.wakeUpScreen -import com.google.common.truth.Truth.assertThat -import org.junit.After -import org.junit.Assume.assumeTrue -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith - -/** Tests for [WearPermissionUsageFragment] */ -@RunWith(AndroidJUnit4::class) -@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) -class WearPermissionUsageFragmentTest : PermissionHub2Test() { - private val CAMERA_APK = - "/data/local/tmp/pc-permissionui/PermissionUiUseCameraPermissionApp.apk" - private val CAMERA_APP_LABEL = "CameraRequestApp" - private val CAMERA_PREF_LABEL = "Camera" - - private val CALENDAR_APK = - "/data/local/tmp/pc-permissionui/PermissionUiReadCalendarPermissionApp.apk" - private val CALENDAR_APP_LABEL = "CalendarRequestApp" - private val CALENDAR_PREF_LABEL = "Calendar" - - private val TEST_PACKAGE_NAME = - "com.android.permissioncontroller.tests.appthatrequestpermission" - - private val SHOW_SYSTEM_LABEL = "Show system" - private val HIDE_SYSTEM_LABEL = "Hide system" - private val TIMEOUT = 30_000L - - @Before - fun setup() { - assumeTrue(isWear()) - wakeUpScreen() - } - - @Test - fun testShowSystem() { - runWithShellPermissionIdentity { - context.startActivity( - Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - } - - clickObject(SHOW_SYSTEM_LABEL) - waitFindObject(By.textContains(HIDE_SYSTEM_LABEL), TIMEOUT) - - clickObject(HIDE_SYSTEM_LABEL) - waitFindObject(By.textContains(SHOW_SYSTEM_LABEL), TIMEOUT) - } - - @Test - fun testTransitToPermissionUsageDetails() { - install(CAMERA_APK) - grantPermission(TEST_PACKAGE_NAME, CAMERA) - accessCamera() - - runWithShellPermissionIdentity { - context.startActivity( - Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - } - - clickObject(CAMERA_PREF_LABEL) - - waitFindObject(By.textContains(CAMERA_APP_LABEL), TIMEOUT) - } - - @Test - fun testTransitToPermissionApps() { - install(CALENDAR_APK) - grantPermission(TEST_PACKAGE_NAME, READ_CALENDAR) - - accessCalendar() - - runWithShellPermissionIdentity { - context.startActivity( - Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - } - - clickObject(CALENDAR_PREF_LABEL) - - waitFindObject(By.textContains(CALENDAR_PREF_LABEL), TIMEOUT) - waitFindObject(By.textContains(CALENDAR_APP_LABEL), TIMEOUT) - } - - private fun accessCalendar() { - runWithShellPermissionIdentity { - eventually { - assertThat( - context.packageManager.getPermissionFlags( - READ_CALENDAR, - TEST_PACKAGE_NAME, - Process.myUserHandle() - ) and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED - ) - .isNotEqualTo(0) - } - - eventually { - assertThat( - context - .getSystemService(AppOpsManager::class.java) - .startOp( - AppOpsManager.OPSTR_READ_CALENDAR, - context.packageManager.getPackageUid(TEST_PACKAGE_NAME, 0), - TEST_PACKAGE_NAME, - null, - null - ) - ) - .isEqualTo(AppOpsManager.MODE_ALLOWED) - } - } - } - - @After - fun tearDown() { - uninstallApp(TEST_PACKAGE_NAME) - pressHome() - } -} diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearUtils.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearUtils.kt deleted file mode 100644 index cf8098f01..000000000 --- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/wear/WearUtils.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.permissioncontroller.permissionui.ui.wear - -import android.content.pm.PackageManager -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.uiautomator.By -import com.android.compatibility.common.util.SystemUtil.eventually -import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObject -import org.junit.Assert.assertNotNull - -private const val TIMEOUT = 30_000L - -fun isWear() = - InstrumentationRegistry.getInstrumentation() - .targetContext - .packageManager - .hasSystemFeature(PackageManager.FEATURE_WATCH) - -fun clickObject(text: String) { - eventually { - val obj = waitFindObject(By.textContains(text), TIMEOUT) - assertNotNull(obj) - obj.click() - } -} diff --git a/SafetyCenter/Config/Android.bp b/SafetyCenter/Config/Android.bp index d6423288a..48c8eab46 100644 --- a/SafetyCenter/Config/Android.bp +++ b/SafetyCenter/Config/Android.bp @@ -40,6 +40,7 @@ java_library { ], static_libs: [ "modules-utils-build", + "permissions-aconfig-flags-lib", ], apex_available: [ "com.android.permission", diff --git a/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java b/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java index b6730f36f..38eee9e51 100644 --- a/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java +++ b/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java @@ -33,10 +33,12 @@ import android.content.res.Resources; import android.safetycenter.config.SafetyCenterConfig; import android.safetycenter.config.SafetySource; import android.safetycenter.config.SafetySourcesGroup; +import android.util.Log; import androidx.annotation.RequiresApi; import com.android.modules.utils.build.SdkLevel; +import com.android.permission.flags.Flags; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -49,6 +51,7 @@ import java.io.InputStream; @RequiresApi(TIRAMISU) public final class SafetyCenterConfigParser { + private static final String TAG = "SafetyCenterConfigParser"; private static final String TAG_SAFETY_CENTER_CONFIG = "safety-center-config"; private static final String TAG_SAFETY_SOURCES_CONFIG = "safety-sources-config"; private static final String TAG_SAFETY_SOURCES_GROUP = "safety-sources-group"; @@ -64,6 +67,8 @@ public final class SafetyCenterConfigParser { private static final String ATTR_SAFETY_SOURCE_PACKAGE_NAME = "packageName"; private static final String ATTR_SAFETY_SOURCE_TITLE = "title"; private static final String ATTR_SAFETY_SOURCE_TITLE_FOR_WORK = "titleForWork"; + private static final String ATTR_SAFETY_SOURCE_TITLE_FOR_PRIVATE_PROFILE = + "titleForPrivateProfile"; private static final String ATTR_SAFETY_SOURCE_SUMMARY = "summary"; private static final String ATTR_SAFETY_SOURCE_INTENT_ACTION = "intentAction"; private static final String ATTR_SAFETY_SOURCE_PROFILE = "profile"; @@ -270,6 +275,26 @@ public final class SafetyCenterConfigParser { parser.getAttributeName(i), resources)); break; + case ATTR_SAFETY_SOURCE_TITLE_FOR_PRIVATE_PROFILE: + if (SdkLevel.isAtLeastV()) { + if (Flags.privateProfileTitleApi()) { + builder.setTitleForPrivateProfileResId( + parseStringResourceName( + parser.getAttributeValue(i), + name, + parser.getAttributeName(i), + resources)); + } else { + Log.i( + TAG, + String.format( + "Ignoring attribute %s.%s", + name, ATTR_SAFETY_SOURCE_TITLE_FOR_PRIVATE_PROFILE)); + } + break; + } else { + throw attributeUnexpected(name, parser.getAttributeName(i)); + } case ATTR_SAFETY_SOURCE_SUMMARY: builder.setSummaryResId( parseStringResourceName( diff --git a/SafetyCenter/Config/tests/Android.bp b/SafetyCenter/Config/tests/Android.bp index 3adedfc25..20a536237 100644 --- a/SafetyCenter/Config/tests/Android.bp +++ b/SafetyCenter/Config/tests/Android.bp @@ -33,6 +33,7 @@ android_test { "compatibility-device-util-axt", "safety-center-config", "safety-center-test-util-lib", + "permissions-aconfig-flags-lib", ], test_suites: [ "general-tests", diff --git a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt index 64775d7fe..e0e16fd71 100644 --- a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt +++ b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt @@ -19,6 +19,7 @@ package com.android.safetycenter.config import android.content.Context import androidx.test.core.app.ApplicationProvider.getApplicationContext import com.android.modules.utils.build.SdkLevel +import com.android.permission.flags.Flags import com.android.safetycenter.config.tests.R import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertThrows @@ -63,18 +64,39 @@ class ParserConfigInvalidTest { fun parameters() = arrayOf( Params( + "ConfigDynamicSafetySourceAllDisabledNoPrivate", + R.raw.config_dynamic_safety_source_all_disabled_no_private, + "Element dynamic-safety-source invalid", + "Required attribute titleForPrivateProfile missing", + SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi() + ), + Params( "ConfigDynamicSafetySourceAllDisabledNoWork", R.raw.config_dynamic_safety_source_all_disabled_no_work, "Element dynamic-safety-source invalid", "Required attribute titleForWork missing" ), Params( + "ConfigDynamicSafetySourceAllHiddenWithSearchNoPrivate", + R.raw.config_dynamic_safety_source_all_hidden_with_search_no_private, + "Element dynamic-safety-source invalid", + "Required attribute titleForPrivateProfile missing", + SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi() + ), + Params( "ConfigDynamicSafetySourceAllHiddenWithSearchNoWork", R.raw.config_dynamic_safety_source_all_hidden_with_search_no_work, "Element dynamic-safety-source invalid", "Required attribute titleForWork missing" ), Params( + "ConfigDynamicSafetySourceAllNoPrivate", + R.raw.config_dynamic_safety_source_all_no_private, + "Element dynamic-safety-source invalid", + "Required attribute titleForPrivateProfile missing", + SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi() + ), + Params( "ConfigDynamicSafetySourceAllNoWork", R.raw.config_dynamic_safety_source_all_no_work, "Element dynamic-safety-source invalid", @@ -160,12 +182,26 @@ class ParserConfigInvalidTest { "Required attribute title missing" ), Params( + "ConfigDynamicSafetySourcePrimaryHiddenWithPrivate", + R.raw.config_dynamic_safety_source_primary_hidden_with_private, + "Element dynamic-safety-source invalid", + "Prohibited attribute titleForPrivateProfile present", + SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi() + ), + Params( "ConfigDynamicSafetySourcePrimaryHiddenWithWork", R.raw.config_dynamic_safety_source_primary_hidden_with_work, "Element dynamic-safety-source invalid", "Prohibited attribute titleForWork present" ), Params( + "ConfigDynamicSafetySourcePrimaryWithPrivate", + R.raw.config_dynamic_safety_source_primary_with_private, + "Element dynamic-safety-source invalid", + "Prohibited attribute titleForPrivateProfile present", + SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi() + ), + Params( "ConfigDynamicSafetySourcePrimaryWithWork", R.raw.config_dynamic_safety_source_primary_with_work, "Element dynamic-safety-source invalid", @@ -226,6 +262,13 @@ class ParserConfigInvalidTest { "Prohibited attribute intentAction present" ), Params( + "ConfigIssueOnlySafetySourceWithPrivate", + R.raw.config_issue_only_safety_source_with_private, + "Element issue-only-safety-source invalid", + "Prohibited attribute titleForPrivateProfile present", + SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi() + ), + Params( "ConfigIssueOnlySafetySourceWithSearch", R.raw.config_issue_only_safety_source_with_search, "Element issue-only-safety-source invalid", @@ -425,12 +468,26 @@ class ParserConfigInvalidTest { SdkLevel.isAtLeastU() ), Params( + "ConfigStaticSafetySourceWithPrimaryAndPrivate", + R.raw.config_static_safety_source_with_primary_and_private, + "Element static-safety-source invalid", + "Prohibited attribute titleForPrivateProfile present", + SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi() + ), + Params( "ConfigStaticSafetySourceWithPrimaryAndWork", R.raw.config_static_safety_source_with_primary_and_work, "Element static-safety-source invalid", "Prohibited attribute titleForWork present" ), Params( + "ConfigStaticSafetySourceWithPrivatePreV", + R.raw.config_static_safety_source_with_private_profile, + "Unexpected attribute static-safety-source.titleForPrivateProfile", + null, + !SdkLevel.isAtLeastV() + ), + Params( "ConfigStaticSafetySourceWithRefresh", R.raw.config_static_safety_source_with_refresh, "Element static-safety-source invalid", diff --git a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt index b63ccead7..133f4ce73 100644 --- a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt +++ b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt @@ -23,6 +23,7 @@ import android.safetycenter.config.SafetySourcesGroup import androidx.test.core.app.ApplicationProvider.getApplicationContext import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.modules.utils.build.SdkLevel +import com.android.permission.flags.Flags import com.android.safetycenter.config.tests.R import com.google.common.truth.Truth.assertThat import org.junit.Test @@ -77,6 +78,9 @@ class ParserConfigValidTest { addPackageCertificateHash("feed1") addPackageCertificateHash("feed2") } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(R.string.reference) + } } .build() ) @@ -101,6 +105,9 @@ class ParserConfigValidTest { addPackageCertificateHash("feed1") addPackageCertificateHash("feed2") } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(R.string.reference) + } } .build() ) @@ -133,6 +140,11 @@ class ParserConfigValidTest { .setProfile(SafetySource.PROFILE_ALL) .setInitialDisplayState(SafetySource.INITIAL_DISPLAY_STATE_HIDDEN) .setSearchTermsResId(R.string.reference) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(R.string.reference) + } + } .build() ) .build() @@ -159,6 +171,11 @@ class ParserConfigValidTest { .setIntentAction("intent") .setProfile(SafetySource.PROFILE_ALL) .setSearchTermsResId(R.string.reference) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(R.string.reference) + } + } .build() ) .build() diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_disabled_no_private.xml b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_disabled_no_private.xml new file mode 100644 index 000000000..dae6ca754 --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_disabled_no_private.xml @@ -0,0 +1,18 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference"> + <dynamic-safety-source + id="id" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="all_profiles" + initialDisplayState="disabled"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_hidden_with_search_no_private.xml b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_hidden_with_search_no_private.xml new file mode 100644 index 000000000..e1852b6ec --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_hidden_with_search_no_private.xml @@ -0,0 +1,17 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference"> + <dynamic-safety-source + id="id" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + profile="all_profiles" + initialDisplayState="hidden" + searchTerms="@com.android.safetycenter.config.tests:string/reference"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_no_private.xml b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_no_private.xml new file mode 100644 index 000000000..8446b71cc --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_all_no_private.xml @@ -0,0 +1,17 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference"> + <dynamic-safety-source + id="id" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="all_profiles"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_primary_hidden_with_private.xml b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_primary_hidden_with_private.xml new file mode 100644 index 000000000..3d5840b03 --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_primary_hidden_with_private.xml @@ -0,0 +1,15 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference"> + <dynamic-safety-source + id="id" + packageName="package" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + profile="primary_profile_only" + initialDisplayState="hidden"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_primary_with_private.xml b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_primary_with_private.xml new file mode 100644 index 000000000..b95a3ed6e --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_dynamic_safety_source_primary_with_private.xml @@ -0,0 +1,17 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference"> + <dynamic-safety-source + id="id" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_issue_only_safety_source_with_private.xml b/SafetyCenter/Config/tests/res/raw-v35/config_issue_only_safety_source_with_private.xml new file mode 100644 index 000000000..7b2484a41 --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_issue_only_safety_source_with_private.xml @@ -0,0 +1,12 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id"> + <issue-only-safety-source + id="id" + packageName="package" + profile="all_profiles" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_static_safety_source_with_primary_and_private.xml b/SafetyCenter/Config/tests/res/raw-v35/config_static_safety_source_with_primary_and_private.xml new file mode 100644 index 000000000..0ab3d885b --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_static_safety_source_with_primary_and_private.xml @@ -0,0 +1,16 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference"> + <static-safety-source + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw-v35/config_valid.xml b/SafetyCenter/Config/tests/res/raw-v35/config_valid.xml new file mode 100644 index 000000000..e49a6cdc4 --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw-v35/config_valid.xml @@ -0,0 +1,197 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="dynamic" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + statelessIconType="privacy"> + <dynamic-safety-source + id="dynamic_barebone" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + <dynamic-safety-source + id="dynamic_all_optional" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="all_profiles" + initialDisplayState="disabled" + maxSeverityLevel="300" + searchTerms="@com.android.safetycenter.config.tests:string/reference" + loggingAllowed="false" + refreshOnPageOpenAllowed="true" + notificationsAllowed="true" + deduplicationGroup="group" + packageCertificateHashes="feed1,feed2"/> + <dynamic-safety-source + id="@com.android.safetycenter.config.tests:string/dynamic_all_references_id" + packageName="@com.android.safetycenter.config.tests:string/dynamic_all_references_package_name" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="@com.android.safetycenter.config.tests:string/dynamic_all_references_intent_action" + profile="@com.android.safetycenter.config.tests:string/dynamic_all_references_profile" + initialDisplayState="@com.android.safetycenter.config.tests:string/dynamic_all_references_initial_display_state" + maxSeverityLevel="@com.android.safetycenter.config.tests:string/dynamic_all_references_max_severity_level" + searchTerms="@com.android.safetycenter.config.tests:string/reference" + loggingAllowed="@com.android.safetycenter.config.tests:string/dynamic_all_references_logging_allowed" + refreshOnPageOpenAllowed="@com.android.safetycenter.config.tests:string/dynamic_all_references_refresh_on_page_open_allowed" + notificationsAllowed="@com.android.safetycenter.config.tests:string/dynamic_all_references_notifications_allowed" + deduplicationGroup="@com.android.safetycenter.config.tests:string/dynamic_all_references_deduplication_group" + packageCertificateHashes="@com.android.safetycenter.config.tests:string/dynamic_all_references_package_cert_hashes"/> + <dynamic-safety-source + id="dynamic_disabled" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + profile="primary_profile_only" + initialDisplayState="disabled"/> + <dynamic-safety-source + id="dynamic_hidden" + packageName="package" + profile="all_profiles" + initialDisplayState="hidden"/> + <dynamic-safety-source + id="dynamic_hidden_with_search" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="all_profiles" + initialDisplayState="hidden" + searchTerms="@com.android.safetycenter.config.tests:string/reference"/> + </safety-sources-group> + <safety-sources-group + id="static" + title="@com.android.safetycenter.config.tests:string/reference"> + <static-safety-source + id="static_barebone" + title="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + <static-safety-source + id="static_all_optional" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="all_profiles" + searchTerms="@com.android.safetycenter.config.tests:string/reference"/> + </safety-sources-group> + <safety-sources-group + id="issue_only"> + <issue-only-safety-source + id="issue_only_barebone" + packageName="package" + profile="primary_profile_only"/> + <issue-only-safety-source + id="issue_only_all_optional" + packageName="package" + profile="all_profiles" + maxSeverityLevel="300" + loggingAllowed="false" + refreshOnPageOpenAllowed="true" + notificationsAllowed="true" + deduplicationGroup="group" + packageCertificateHashes="feed1,feed2"/> + <issue-only-safety-source + id="id_test_abcxyz_ABCXYZ_012789" + packageName="package" + profile="primary_profile_only"/> + </safety-sources-group> + <safety-sources-group + id="mixed" + title="@com.android.safetycenter.config.tests:string/reference"> + <dynamic-safety-source + id="mixed_dynamic_barebone" + packageName="package" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + <issue-only-safety-source + id="mixed_issue_only_barebone" + packageName="package" + profile="primary_profile_only"/> + <static-safety-source + id="mixed_static_barebone" + title="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + </safety-sources-group> + <safety-sources-group + type="stateful" + id="stateful_barebone" + title="@com.android.safetycenter.config.tests:string/reference"> + <static-safety-source + id="stateful_barebone_source" + title="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + </safety-sources-group> + <safety-sources-group + type="stateful" + id="stateful_all_optional" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + statelessIconType="privacy"> + <static-safety-source + id="stateful_all_optional_source" + title="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + </safety-sources-group> + <safety-sources-group + type="stateless" + id="stateless_barebone" + title="@com.android.safetycenter.config.tests:string/reference"> + <static-safety-source + id="stateless_barebone_source" + title="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + </safety-sources-group> + <safety-sources-group + type="stateless" + id="stateless_all_optional" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + statelessIconType="privacy"> + <static-safety-source + id="stateless_all_optional_source" + title="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="primary_profile_only"/> + </safety-sources-group> + <safety-sources-group + type="hidden" + id="hidden_barebone"> + <issue-only-safety-source + id="hidden_barebone_source" + packageName="package" + profile="primary_profile_only"/> + </safety-sources-group> + <safety-sources-group + type="hidden" + id="hidden_all_optional" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + statelessIconType="privacy"> + <issue-only-safety-source + id="hidden_all_optional_source" + packageName="package" + profile="primary_profile_only"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/Config/tests/res/raw/config_static_safety_source_with_private_profile.xml b/SafetyCenter/Config/tests/res/raw/config_static_safety_source_with_private_profile.xml new file mode 100644 index 000000000..f790baec9 --- /dev/null +++ b/SafetyCenter/Config/tests/res/raw/config_static_safety_source_with_private_profile.xml @@ -0,0 +1,17 @@ +<safety-center-config> + <safety-sources-config> + <safety-sources-group + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference"> + <static-safety-source + id="id" + title="@com.android.safetycenter.config.tests:string/reference" + titleForWork="@com.android.safetycenter.config.tests:string/reference" + titleForPrivateProfile="@com.android.safetycenter.config.tests:string/reference" + summary="@com.android.safetycenter.config.tests:string/reference" + intentAction="intent" + profile="all_profiles"/> + </safety-sources-group> + </safety-sources-config> +</safety-center-config> diff --git a/SafetyCenter/ConfigLintChecker/Android.bp b/SafetyCenter/ConfigLintChecker/Android.bp index fad0165df..7c615d2f4 100644 --- a/SafetyCenter/ConfigLintChecker/Android.bp +++ b/SafetyCenter/ConfigLintChecker/Android.bp @@ -12,64 +12,65 @@ // See the License for the specific language governing permissions and // limitations under the License. -package { - default_team: "trendy_team_android_permissions", - default_applicable_licenses: ["Android-Apache-2.0"], -} +// TODO(b/322944911): Reconsider enabling linter checker +//package { +// default_team: "trendy_team_android_permissions", +// default_applicable_licenses: ["Android-Apache-2.0"], +//} -java_library_host { - name: "ConfigLintChecker", - srcs: [ - "java/**/*.java", - "java/**/*.kt", - ":safetycenter-annotations-sources", - ":safetycenter-config-api-sources", - ":safetycenter-config-parser-sources", - ], - plugins: ["auto_service_plugin"], - libs: [ - "androidx.annotation_annotation", // For androidx.annotation.RequiresApi - "auto_service_annotations", - "core-xml-for-host", // For org.xmlpull.v1.* - "framework-annotations-lib", // For com.android.annotation.* - "layoutlib_api-prebuilt", // For com.android.resources.ResourceFolderType - "lint_api", - ], - java_resources: [":safetycenter-config-schemas"], - jarjar_rules: "jarjar-rules.txt", - kotlincflags: ["-Xjvm-default=all"], - visibility: [ - "//packages/modules/Permission:__subpackages__", - "//vendor:__subpackages__", - ], -} +//java_library_host { +// name: "ConfigLintChecker", +// srcs: [ +// "java/**/*.java", +// "java/**/*.kt", +// ":safetycenter-annotations-sources", +// ":safetycenter-config-api-sources", +// ":safetycenter-config-parser-sources", +// ], +// plugins: ["auto_service_plugin"], +// libs: [ +// "androidx.annotation_annotation", // For androidx.annotation.RequiresApi +// "auto_service_annotations", +// "core-xml-for-host", // For org.xmlpull.v1.* +// "framework-annotations-lib", // For com.android.annotation.* +// "layoutlib_api-prebuilt", // For com.android.resources.ResourceFolderType +// "lint_api", +// ], +// java_resources: [":safetycenter-config-schemas"], +// jarjar_rules: "jarjar-rules.txt", +// kotlincflags: ["-Xjvm-default=all"], +// visibility: [ +// "//packages/modules/Permission:__subpackages__", +// "//vendor:__subpackages__", +// ], +//} -java_test_host { - name: "ConfigLintCheckerTest", - srcs: [ - "tests/java/**/*.kt", - ], - static_libs: [ - "ConfigLintChecker", - "junit", - "lint", - "lint_tests", - ], - test_options: { - unit_test: true, - tradefed_options: [ - { - // lint bundles in some classes that were built with older versions - // of libraries, and no longer load. Since tradefed tries to load - // all classes in the jar to look for tests, it crashes loading them. - // Exclude these classes from tradefed's search. - name: "exclude-paths", - value: "org/apache", - }, - { - name: "exclude-paths", - value: "META-INF", - }, - ], - }, -} +//java_test_host { +// name: "ConfigLintCheckerTest", +// srcs: [ +// "tests/java/**/*.kt", +// ], +// static_libs: [ +// "ConfigLintChecker", +// "junit", +// "lint", +// "lint_tests", +// ], +// test_options: { +// unit_test: true, +// tradefed_options: [ +// { +// // lint bundles in some classes that were built with older versions +// // of libraries, and no longer load. Since tradefed tries to load +// // all classes in the jar to look for tests, it crashes loading them. +// // Exclude these classes from tradefed's search. +// name: "exclude-paths", +// value: "org/apache", +// }, +// { +// name: "exclude-paths", +// value: "META-INF", +// }, +// ], +// }, +//} diff --git a/SafetyCenter/Resources/Android.bp b/SafetyCenter/Resources/Android.bp index 6f635c885..a10ea7f1a 100644 --- a/SafetyCenter/Resources/Android.bp +++ b/SafetyCenter/Resources/Android.bp @@ -42,9 +42,10 @@ android_app { min_sdk_version: "30", apex_available: ["com.android.permission"], certificate: ":com.android.safetycenter.resources.certificate", - lint: { - extra_check_modules: ["ConfigLintChecker"], - }, + // TODO(b/322944911): Reconsider enabling linter checker + //lint: { + // extra_check_modules: ["ConfigLintChecker"], + //}, static_libs: [ "SafetyCenterResourcesShared", ], diff --git a/SafetyCenter/Resources/res/raw-v35/safety_center_config.xml b/SafetyCenter/Resources/res/raw-v35/safety_center_config.xml index 83369f920..cb49e9d36 100644 --- a/SafetyCenter/Resources/res/raw-v35/safety_center_config.xml +++ b/SafetyCenter/Resources/res/raw-v35/safety_center_config.xml @@ -35,10 +35,22 @@ profile="all_profiles" title="@com.android.safetycenter.resources:string/biometrics_title" titleForWork="@com.android.safetycenter.resources:string/biometrics_title_for_work" + titleForPrivateProfile="@com.android.safetycenter.resources:string/biometrics_title_for_private_profile" searchTerms="@com.android.safetycenter.resources:string/biometrics_search_terms" initialDisplayState="hidden"/> </safety-sources-group> <safety-sources-group + id="AndroidCellularNetworkSecuritySources" + title="@com.android.safetycenter.resources:string/cellular_network_security_title" + summary="@com.android.safetycenter.resources:string/cellular_network_security_summary"> + <dynamic-safety-source + id="AndroidCellularNetworkSecurity" + packageName="com.android.phone" + profile="primary_profile_only" + notificationsAllowed="true" + initialDisplayState="hidden"/> + </safety-sources-group> + <safety-sources-group id="AndroidPrivacySources" title="@com.android.safetycenter.resources:string/privacy_sources_title" summary="@com.android.safetycenter.resources:string/privacy_sources_summary" diff --git a/SafetyCenter/Resources/res/values-af-v35/strings.xml b/SafetyCenter/Resources/res/values-af-v35/strings.xml index 2990bde0d..ab7ce0129 100644 --- a/SafetyCenter/Resources/res/values-af-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-af-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Selnetwerksekuriteit"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Netwerktipe, enkripsie, kennisgewingkontroles"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privaat ruimte"</string> <string name="private_space_summary" msgid="529869826714610294">"Stel privaat ruimte op, en meer"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privaat ruimte"</string> diff --git a/SafetyCenter/Resources/res/values-am-v35/strings.xml b/SafetyCenter/Resources/res/values-am-v35/strings.xml index 290a8816c..96f9ade78 100644 --- a/SafetyCenter/Resources/res/values-am-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-am-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"የተንቀሳቃሽ ስልክ አውታረ መረብ ደህንነት"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"የአውታረ መረብ ዓይነት፣ ምስጠራ፣ የማሳወቂያ መቆጣጠሪያዎች"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"የግል ቦታ"</string> <string name="private_space_summary" msgid="529869826714610294">"የግል ቦታን እና ሌሎችን ያዋቅሩ"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"የግል ቦታ"</string> diff --git a/SafetyCenter/Resources/res/values-ar-v35/strings.xml b/SafetyCenter/Resources/res/values-ar-v35/strings.xml index 29fc7583d..4cf1c9a07 100644 --- a/SafetyCenter/Resources/res/values-ar-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ar-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"أمان شبكة الجوّال"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"عناصر التحكم في نوع الشبكة والتشفير والإشعارات"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"مساحة خاصة"</string> <string name="private_space_summary" msgid="529869826714610294">"ضبط إعدادات مساحة خاصة وغير ذلك"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"مساحة خاصة"</string> diff --git a/SafetyCenter/Resources/res/values-as-v35/strings.xml b/SafetyCenter/Resources/res/values-as-v35/strings.xml index 71918ea36..905e1567c 100644 --- a/SafetyCenter/Resources/res/values-as-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-as-v35/strings.xml @@ -17,7 +17,10 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="private_space_title" msgid="6158245041481535879">"ব্যক্তিগত স্পে’চ"</string> - <string name="private_space_summary" msgid="529869826714610294">"ব্যক্তিগত স্পে’চ আৰু আন বহুতো ছেটআপ কৰক"</string> - <string name="private_space_search_terms" msgid="4820808478299116258">"ব্যক্তিগত স্পে’চ"</string> + <string name="cellular_network_security_title" msgid="2986431282931510973">"চেলুলাৰ নেটৱৰ্কৰ সুৰক্ষা"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"নেটৱৰ্কৰ প্ৰকাৰ, এনক্ৰিপশ্বন, জাননীৰ নিয়ন্ত্ৰণসমূহ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> + <string name="private_space_title" msgid="6158245041481535879">"প্ৰাইভেট স্পে\'চ"</string> + <string name="private_space_summary" msgid="529869826714610294">"প্ৰাইভেট স্পে\'চ আৰু আন বহুতো ছেটআপ কৰক"</string> + <string name="private_space_search_terms" msgid="4820808478299116258">"প্ৰাইভেট স্পে\'চ"</string> </resources> diff --git a/SafetyCenter/Resources/res/values-az-v35/strings.xml b/SafetyCenter/Resources/res/values-az-v35/strings.xml index e1fd4c181..33b8aa0da 100644 --- a/SafetyCenter/Resources/res/values-az-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-az-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobil şəbəkə təhlükəsizliyi"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Şəbəkə növü, şifrələmə, bildiriş nizamlayıcıları"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Şəxsi yer"</string> <string name="private_space_summary" msgid="529869826714610294">"Şəxsi yer və s. ayarlayın"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Şəxsi yer"</string> diff --git a/SafetyCenter/Resources/res/values-b+sr+Latn-v35/strings.xml b/SafetyCenter/Resources/res/values-b+sr+Latn-v35/strings.xml index 6a52a1a8d..6584b80b5 100644 --- a/SafetyCenter/Resources/res/values-b+sr+Latn-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-b+sr+Latn-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Bezbednost mobilne mreže"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tip mreže, šifrovanje, kontrole obaveštenja"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privatni prostor"</string> <string name="private_space_summary" msgid="529869826714610294">"Podesite privatni prostor i drugo"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privatni prostor"</string> diff --git a/SafetyCenter/Resources/res/values-b+sr+Latn/strings.xml b/SafetyCenter/Resources/res/values-b+sr+Latn/strings.xml index c4328fe12..628477b14 100644 --- a/SafetyCenter/Resources/res/values-b+sr+Latn/strings.xml +++ b/SafetyCenter/Resources/res/values-b+sr+Latn/strings.xml @@ -22,7 +22,7 @@ <string name="lock_screen_sources_summary" msgid="7220439741282516496"></string> <string name="lock_screen_title" msgid="4069104894527169877">"Otključavanje ekrana"</string> <string name="lock_screen_summary_disabled" msgid="354071230916616692">"Još nema informacija"</string> - <string name="lock_screen_search_terms" msgid="2678486357779794826">"zaključavanje uređaja, zaključavanje ekrana, zaključani ekran, lozinka, PIN, šablon"</string> + <string name="lock_screen_search_terms" msgid="2678486357779794826">"zaključavanje uređaja, otključavanje ekrana, zaključani ekran, lozinka, PIN, šablon"</string> <string name="biometrics_title" msgid="5859504610285212938">"Biometrija"</string> <string name="biometrics_search_terms" msgid="6040319118762671981">"otisak prsta, prst, dodaj otisak prsta, otključavanje licem, lice"</string> <string name="privacy_sources_title" msgid="4061110826457365957">"Privatnost"</string> diff --git a/SafetyCenter/Resources/res/values-be-v35/strings.xml b/SafetyCenter/Resources/res/values-be-v35/strings.xml index c8db4cb50..61d96987a 100644 --- a/SafetyCenter/Resources/res/values-be-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-be-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Бяспека сотавай сеткі"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Тып сеткі, шыфраванне, налады апавяшчэнняў"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Прыватная вобласць"</string> <string name="private_space_summary" msgid="529869826714610294">"Наладжванне прыватнай вобласці і не толькі"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Прыватная вобласць"</string> diff --git a/SafetyCenter/Resources/res/values-bg-v35/strings.xml b/SafetyCenter/Resources/res/values-bg-v35/strings.xml index bb78de8a5..09060c431 100644 --- a/SafetyCenter/Resources/res/values-bg-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-bg-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Сигурност на мобилната мрежа"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Тип мрежа, шифроване, контроли за известията"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Лично пространство"</string> <string name="private_space_summary" msgid="529869826714610294">"Настройване на лично пространство и др."</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Лично пространство"</string> diff --git a/SafetyCenter/Resources/res/values-bn-v35/strings.xml b/SafetyCenter/Resources/res/values-bn-v35/strings.xml index 5b05d3b7e..27ec98325 100644 --- a/SafetyCenter/Resources/res/values-bn-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-bn-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"মোবাইল নেটওয়ার্কের সুরক্ষা"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"নেটওয়ার্কের ধরন, এনক্রিপশন, বিজ্ঞপ্তির নিয়ন্ত্রণ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"ব্যক্তিগত স্পেস"</string> <string name="private_space_summary" msgid="529869826714610294">"\'ব্যক্তিগত স্পেস\' সেট-আপ ও আরও অনেক কিছু করুন"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"ব্যক্তিগত স্পেস"</string> diff --git a/SafetyCenter/Resources/res/values-bs-v35/strings.xml b/SafetyCenter/Resources/res/values-bs-v35/strings.xml index ab9d9d6ba..e962785aa 100644 --- a/SafetyCenter/Resources/res/values-bs-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-bs-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sigurnost mobilne mreže"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Vrsta mreže, šifriranje i kontrole obavještenja"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privatni prostor"</string> <string name="private_space_summary" msgid="529869826714610294">"Postavite privatni prostor i drugo"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privatni prostor"</string> diff --git a/SafetyCenter/Resources/res/values-ca-v35/strings.xml b/SafetyCenter/Resources/res/values-ca-v35/strings.xml index ba0cc5dd2..7517723a5 100644 --- a/SafetyCenter/Resources/res/values-ca-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ca-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Seguretat de la xarxa mòbil"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipus de xarxa, encriptació, controls de notificació"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espai privat"</string> <string name="private_space_summary" msgid="529869826714610294">"Configura l\'espai privat i més"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espai privat"</string> diff --git a/SafetyCenter/Resources/res/values-cs-v35/strings.xml b/SafetyCenter/Resources/res/values-cs-v35/strings.xml index 532449ee1..443d815e2 100644 --- a/SafetyCenter/Resources/res/values-cs-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-cs-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Zabezpečení mobilní sítě"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Nastavení typu sítě, šifrování a oznámení"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Soukromý prostor"</string> <string name="private_space_summary" msgid="529869826714610294">"Nastavte si Soukromý prostor atd."</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Soukromý prostor"</string> diff --git a/SafetyCenter/Resources/res/values-da-v35/strings.xml b/SafetyCenter/Resources/res/values-da-v35/strings.xml index 9401dbbe7..25c638325 100644 --- a/SafetyCenter/Resources/res/values-da-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-da-v35/strings.xml @@ -17,7 +17,10 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="private_space_title" msgid="6158245041481535879">"Privat rum"</string> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sikkerhed for mobilnetværk"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Netværkstype, kryptering, notifikationsstyring"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> + <string name="private_space_title" msgid="6158245041481535879">"Privat område"</string> <string name="private_space_summary" msgid="529869826714610294">"Konfigurer et privat rum m.m."</string> - <string name="private_space_search_terms" msgid="4820808478299116258">"Privat rum"</string> + <string name="private_space_search_terms" msgid="4820808478299116258">"Privat område"</string> </resources> diff --git a/SafetyCenter/Resources/res/values-de-v35/strings.xml b/SafetyCenter/Resources/res/values-de-v35/strings.xml index 22f254518..5c3818eaa 100644 --- a/SafetyCenter/Resources/res/values-de-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-de-v35/strings.xml @@ -17,7 +17,10 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="private_space_title" msgid="6158245041481535879">"Privater Bereich"</string> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sicherheit von Mobilfunknetzen"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Netzwerktyp, Verschlüsselung, Benachrichtigungseinstellungen"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> + <string name="private_space_title" msgid="6158245041481535879">"Privates Profil"</string> <string name="private_space_summary" msgid="529869826714610294">"Privaten Bereich einrichten und mehr"</string> - <string name="private_space_search_terms" msgid="4820808478299116258">"Privater Bereich"</string> + <string name="private_space_search_terms" msgid="4820808478299116258">"Privates Profil"</string> </resources> diff --git a/SafetyCenter/Resources/res/values-el-v35/strings.xml b/SafetyCenter/Resources/res/values-el-v35/strings.xml index 5cea492f7..3b1c02a6d 100644 --- a/SafetyCenter/Resources/res/values-el-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-el-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Ασφάλεια δικτύου κινητής τηλεφωνίας"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Τύπος δικτύου, κρυπτογράφηση, στοιχεία ελέγχου ειδοποιήσεων"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Ιδιωτικός χώρος"</string> <string name="private_space_summary" msgid="529869826714610294">"Ρύθμιση Ιδιωτικού χώρου κ.ά."</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Ιδιωτικός χώρος"</string> diff --git a/SafetyCenter/Resources/res/values-en-rAU-v35/strings.xml b/SafetyCenter/Resources/res/values-en-rAU-v35/strings.xml index 311c5ca42..42d1921e2 100644 --- a/SafetyCenter/Resources/res/values-en-rAU-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-en-rAU-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobile network security"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Network type, encryption, notification controls"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Private Space"</string> <string name="private_space_summary" msgid="529869826714610294">"Set up Private Space, and more"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Private Space"</string> diff --git a/SafetyCenter/Resources/res/values-en-rCA-v35/strings.xml b/SafetyCenter/Resources/res/values-en-rCA-v35/strings.xml index e0c36a7a0..c8dea5d1f 100644 --- a/SafetyCenter/Resources/res/values-en-rCA-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-en-rCA-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Cellular network security"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Network type, encryption, notification controls"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Private Space"</string> <string name="private_space_summary" msgid="529869826714610294">"Setup Private Space, and more"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Private Space"</string> diff --git a/SafetyCenter/Resources/res/values-en-rGB-v35/strings.xml b/SafetyCenter/Resources/res/values-en-rGB-v35/strings.xml index 311c5ca42..42d1921e2 100644 --- a/SafetyCenter/Resources/res/values-en-rGB-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-en-rGB-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobile network security"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Network type, encryption, notification controls"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Private Space"</string> <string name="private_space_summary" msgid="529869826714610294">"Set up Private Space, and more"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Private Space"</string> diff --git a/SafetyCenter/Resources/res/values-en-rIN-v35/strings.xml b/SafetyCenter/Resources/res/values-en-rIN-v35/strings.xml index 311c5ca42..42d1921e2 100644 --- a/SafetyCenter/Resources/res/values-en-rIN-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-en-rIN-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobile network security"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Network type, encryption, notification controls"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Private Space"</string> <string name="private_space_summary" msgid="529869826714610294">"Set up Private Space, and more"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Private Space"</string> diff --git a/SafetyCenter/Resources/res/values-en-rXC-v35/strings.xml b/SafetyCenter/Resources/res/values-en-rXC-v35/strings.xml index ad86de92f..998df375a 100644 --- a/SafetyCenter/Resources/res/values-en-rXC-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-en-rXC-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Cellular network security"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Network type, encryption, notification controls"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Private Space"</string> <string name="private_space_summary" msgid="529869826714610294">"Setup Private Space, and more"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Private Space"</string> diff --git a/SafetyCenter/Resources/res/values-es-rUS-v35/strings.xml b/SafetyCenter/Resources/res/values-es-rUS-v35/strings.xml index 323af67b1..7b63e6630 100644 --- a/SafetyCenter/Resources/res/values-es-rUS-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-es-rUS-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Seguridad de red móvil"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipo de red, encriptación, controles de notificaciones"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espacio privado"</string> <string name="private_space_summary" msgid="529869826714610294">"Configura el Espacio privado y mucho más"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espacio privado"</string> diff --git a/SafetyCenter/Resources/res/values-es-v35/strings.xml b/SafetyCenter/Resources/res/values-es-v35/strings.xml index 9901be878..775de899b 100644 --- a/SafetyCenter/Resources/res/values-es-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-es-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Seguridad de la red móvil"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipo de red, cifrado, controles de notificaciones"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espacio privado"</string> <string name="private_space_summary" msgid="529869826714610294">"Configura el espacio privado y más"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espacio privado"</string> diff --git a/SafetyCenter/Resources/res/values-et-v35/strings.xml b/SafetyCenter/Resources/res/values-et-v35/strings.xml index e2f169a10..0fdaadbe2 100644 --- a/SafetyCenter/Resources/res/values-et-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-et-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobiilsidevõrgu turvalisus"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Võrgu tüüp, krüpteerimine, märguannete juhtnupud"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privaatne ruum"</string> <string name="private_space_summary" msgid="529869826714610294">"Privaatse ruumi seadistamine ja muu"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privaatne ruum"</string> diff --git a/SafetyCenter/Resources/res/values-eu-v34/strings.xml b/SafetyCenter/Resources/res/values-eu-v34/strings.xml index 20f2cfbaf..0d257905b 100644 --- a/SafetyCenter/Resources/res/values-eu-v34/strings.xml +++ b/SafetyCenter/Resources/res/values-eu-v34/strings.xml @@ -25,7 +25,7 @@ <string name="app_data_sharing_updates_title" msgid="7428862330643262588">"Kokapen-datuak partekatzeko aukeraren berritasunak"</string> <string name="app_data_sharing_updates_search_terms" msgid="8414777373734245398">"datuak, datuak partekatzeko aukera, datuak partekatzeko aukeraren berritasunak, kokapen-datuak partekatzeko aukeraren berritasunak, partekatzea"</string> <string name="advanced_title" msgid="6259362998269627310">"Beste ezarpen batzuk"</string> - <string name="more_settings_title" msgid="9033454654010697185">"Segurtasun eta pribatutasun gehiago"</string> + <string name="more_settings_title" msgid="9033454654010697185">"Segurtasun eta pribatutasun handiagoa"</string> <string name="more_settings_summary" msgid="7086620830002515710">"Betetze automatikoa, jakinarazpenak eta abar"</string> <string name="more_settings_search_terms" msgid="1371913937610933955"></string> <string name="work_policy_title" msgid="915692932391542104">"Laneko gidalerroei buruzko informazioa"</string> diff --git a/SafetyCenter/Resources/res/values-eu-v35/strings.xml b/SafetyCenter/Resources/res/values-eu-v35/strings.xml index c22f585ab..d61be7014 100644 --- a/SafetyCenter/Resources/res/values-eu-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-eu-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sare mugikorraren segurtasuna"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Sare mota, enkriptatzea, jakinarazpenak kontrolatzeko aukerak"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Eremu pribatua"</string> <string name="private_space_summary" msgid="529869826714610294">"Konfiguratu eremu pribatua eta abar"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Eremu pribatua"</string> diff --git a/SafetyCenter/Resources/res/values-fa-v34/strings.xml b/SafetyCenter/Resources/res/values-fa-v34/strings.xml index d8bf2b762..92a2168de 100644 --- a/SafetyCenter/Resources/res/values-fa-v34/strings.xml +++ b/SafetyCenter/Resources/res/values-fa-v34/strings.xml @@ -18,7 +18,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="lock_screen_sources_title" msgid="5493678510117489865">"باز کردن قفل دستگاه"</string> - <string name="biometrics_title_for_work" msgid="1842284049407771568">"گزینههای زیستسنجشی ویژه کار"</string> + <string name="biometrics_title_for_work" msgid="1842284049407771568">"دادههای زیستسنجشی برای کار"</string> <string name="privacy_sources_summary" msgid="4083646673569677049">"اجازهها، داشبورد، کنترلها"</string> <string name="health_connect_title" msgid="8318152190040327804">"Health Connect"</string> <string name="health_connect_search_terms" msgid="4998970586245680829">"سلامت، Health Connect"</string> diff --git a/SafetyCenter/Resources/res/values-fa-v35/strings.xml b/SafetyCenter/Resources/res/values-fa-v35/strings.xml index a3eb194ee..ee5e56422 100644 --- a/SafetyCenter/Resources/res/values-fa-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-fa-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"امنیت شبکه تلفن همراه"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"نوع شبکه، رمزگذاری، کنترلهای اعلان"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"فضای خصوصی"</string> <string name="private_space_summary" msgid="529869826714610294">"راهاندازی «فضای خصوصی»، و موارد دیگر"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"فضای خصوصی"</string> diff --git a/SafetyCenter/Resources/res/values-fa/strings.xml b/SafetyCenter/Resources/res/values-fa/strings.xml index 41a3121ea..bdf2063f1 100644 --- a/SafetyCenter/Resources/res/values-fa/strings.xml +++ b/SafetyCenter/Resources/res/values-fa/strings.xml @@ -23,7 +23,7 @@ <string name="lock_screen_title" msgid="4069104894527169877">"قفل صفحه"</string> <string name="lock_screen_summary_disabled" msgid="354071230916616692">"هنوز اطلاعاتی دردسترس نیست"</string> <string name="lock_screen_search_terms" msgid="2678486357779794826">"قفل دستگاه، قفل صفحه، صفحه قفل، صفحهقفل، گذرواژه، پین، الگو"</string> - <string name="biometrics_title" msgid="5859504610285212938">"زیستسنجشی"</string> + <string name="biometrics_title" msgid="5859504610285212938">"دادههای زیستسنجشی"</string> <string name="biometrics_search_terms" msgid="6040319118762671981">"اثر انگشت، انگشت، افزودن اثر انگشت، قفلگشایی با چهره، چهره"</string> <string name="privacy_sources_title" msgid="4061110826457365957">"حریم خصوصی"</string> <string name="privacy_sources_summary" msgid="4089719981155120864">"داشبورد، اجازهها، کنترلها"</string> @@ -37,7 +37,7 @@ <string name="privacy_controls_summary" msgid="2402066941190435424">"کنترل دسترسی دستگاه به میکروفون، دوربین، و غیره"</string> <string name="privacy_controls_search_terms" msgid="3774472175934304165">"حریم خصوصی، تنظیمات حریم خصوصی"</string> <string name="advanced_title" msgid="8745436380690561172">"تنظیمات بیشتر"</string> - <string name="advanced_security_title" msgid="1126833338772188155">"تنظیمات امنیتی بیشتر"</string> + <string name="advanced_security_title" msgid="1126833338772188155">"تنظیمات ایمنی بیشتر"</string> <string name="advanced_security_summary" msgid="6172253327022425123">"رمزگذاری، اطلاعات اعتباری، و غیره"</string> <string name="advanced_security_search_terms" msgid="3350609555814362075"></string> <string name="advanced_privacy_title" msgid="1117725225706176643">"تنظیمات حریم خصوصی بیشتر"</string> diff --git a/SafetyCenter/Resources/res/values-fi-v35/strings.xml b/SafetyCenter/Resources/res/values-fi-v35/strings.xml index c80c17207..52594a08c 100644 --- a/SafetyCenter/Resources/res/values-fi-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-fi-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobiiliverkon tietoturva"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Verkon tyyppi, salaus, ilmoitusvalinnat"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Yksityinen tila"</string> <string name="private_space_summary" msgid="529869826714610294">"Ota esimerkiksi yksityinen tila käyttöön"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Yksityinen tila"</string> diff --git a/SafetyCenter/Resources/res/values-fi/strings.xml b/SafetyCenter/Resources/res/values-fi/strings.xml index de46fb233..5d234cd05 100644 --- a/SafetyCenter/Resources/res/values-fi/strings.xml +++ b/SafetyCenter/Resources/res/values-fi/strings.xml @@ -30,7 +30,7 @@ <string name="permission_usage_title" msgid="3633779688945350407">"Yksityisyydenhallintapaneeli"</string> <string name="permission_usage_summary" msgid="5323079206029964468">"Näytä, mitkä sovellukset ovat käyttäneet lupia äskettäin"</string> <string name="permission_usage_search_terms" msgid="3852343592870257104">"Yksityisyys, yksityisyydenhallintapaneeli"</string> - <string name="permission_manager_title" msgid="5277347862821255015">"Lupien ylläpito"</string> + <string name="permission_manager_title" msgid="5277347862821255015">"Lupienhallinta"</string> <string name="permission_manager_summary" msgid="8099852107340970790">"Päätä sovelluksen pääsystä dataasi"</string> <string name="permission_manager_search_terms" msgid="2895147613099694722">"Luvat, lupien hallinta"</string> <string name="privacy_controls_title" msgid="5322875777945432395">"Yksityisyysasetukset"</string> @@ -41,6 +41,6 @@ <string name="advanced_security_summary" msgid="6172253327022425123">"Salaus, kirjautumistiedot ja muuta"</string> <string name="advanced_security_search_terms" msgid="3350609555814362075"></string> <string name="advanced_privacy_title" msgid="1117725225706176643">"Lisää yksityisyysasetuksia"</string> - <string name="advanced_privacy_summary" msgid="2281203390575069543">"Automaattinen täyttö, toimintojen hallinta ja muuta"</string> + <string name="advanced_privacy_summary" msgid="2281203390575069543">"Automaattinen täyttö, toiminnan hallinta ja muuta"</string> <string name="advanced_privacy_search_terms" msgid="5044404599789175222"></string> </resources> diff --git a/SafetyCenter/Resources/res/values-fr-rCA-v35/strings.xml b/SafetyCenter/Resources/res/values-fr-rCA-v35/strings.xml index 06d909df8..d762c9db0 100644 --- a/SafetyCenter/Resources/res/values-fr-rCA-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-fr-rCA-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sécurité du réseau cellulaire"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Contrôles du type de réseau, du chiffrement et des notifications"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espace privé"</string> <string name="private_space_summary" msgid="529869826714610294">"Configuration de l\'espace privé, et plus"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espace privé"</string> diff --git a/SafetyCenter/Resources/res/values-fr-v35/strings.xml b/SafetyCenter/Resources/res/values-fr-v35/strings.xml index a1ba13767..1371aa9f2 100644 --- a/SafetyCenter/Resources/res/values-fr-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-fr-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sécurité des réseaux mobiles"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Type de réseau, chiffrement, paramètres de notifications"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espace privé"</string> <string name="private_space_summary" msgid="529869826714610294">"Configurez votre espace privé et bien plus"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espace privé"</string> diff --git a/SafetyCenter/Resources/res/values-gl-v35/strings.xml b/SafetyCenter/Resources/res/values-gl-v35/strings.xml index 52586da18..4275d9484 100644 --- a/SafetyCenter/Resources/res/values-gl-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-gl-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Seguranza da rede de telefonía móbil"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipo de rede, encriptación, controis de notificacións"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espazo privado"</string> <string name="private_space_summary" msgid="529869826714610294">"Configura o espazo privado e moito máis"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espazo privado"</string> diff --git a/SafetyCenter/Resources/res/values-gu-v35/strings.xml b/SafetyCenter/Resources/res/values-gu-v35/strings.xml index 23dfe440a..a4a781e12 100644 --- a/SafetyCenter/Resources/res/values-gu-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-gu-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"સેલ્યુલર નેટવર્ક સંબંધી સુરક્ષા"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"નેટવર્કનો પ્રકાર, એન્ક્રિપ્શન, નોટિફિકેશનના નિયંત્રણો"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"ખાનગી સ્પેસ"</string> <string name="private_space_summary" msgid="529869826714610294">"ખાનગી સ્પેસનું સેટઅપ કરો અને બીજું ઘણું કરો"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"ખાનગી સ્પેસ"</string> diff --git a/SafetyCenter/Resources/res/values-hi-v35/strings.xml b/SafetyCenter/Resources/res/values-hi-v35/strings.xml index ca4b78965..c0a084f7b 100644 --- a/SafetyCenter/Resources/res/values-hi-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-hi-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"मोबाइल नेटवर्क की सुरक्षा"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"नेटवर्क टाइप, एन्क्रिप्ट करने का तरीका, सूचनाएं कंट्रोल करने की सेटिंग"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"प्राइवेट स्पेस"</string> <string name="private_space_summary" msgid="529869826714610294">"प्राइवेट स्पेस सेटअप करें और अन्य काम करें"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"प्राइवेट स्पेस"</string> diff --git a/SafetyCenter/Resources/res/values-hr-v35/strings.xml b/SafetyCenter/Resources/res/values-hr-v35/strings.xml index 024be31b1..f9ce54f32 100644 --- a/SafetyCenter/Resources/res/values-hr-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-hr-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sigurnost mobilne mreže"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Vrsta mreže, šifriranje, kontrole obavijesti"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privatni prostor"</string> <string name="private_space_summary" msgid="529869826714610294">"Postavljanje privatnog prostora i drugo"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privatni prostor"</string> diff --git a/SafetyCenter/Resources/res/values-hu-v35/strings.xml b/SafetyCenter/Resources/res/values-hu-v35/strings.xml index 0fe083899..0c77b2181 100644 --- a/SafetyCenter/Resources/res/values-hu-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-hu-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobilhálózat biztonsága"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Hálózattípus, titkosítás, értesítésvezérlők"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privát terület"</string> <string name="private_space_summary" msgid="529869826714610294">"Privát terület beállítása és egyebek"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privát terület"</string> diff --git a/SafetyCenter/Resources/res/values-hy-v35/strings.xml b/SafetyCenter/Resources/res/values-hy-v35/strings.xml index 54487ffa8..1b9c3ffdc 100644 --- a/SafetyCenter/Resources/res/values-hy-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-hy-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Բջջային ցանցի անվտանգություն"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Ցանցի տեսակը, գաղտնագրում, ծանուցումների կառավարում"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Անձնական տարածք"</string> <string name="private_space_summary" msgid="529869826714610294">"Կարգավորեք անձնական տարածքը և ավելին"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Անձնական տարածք"</string> diff --git a/SafetyCenter/Resources/res/values-in-v34/strings.xml b/SafetyCenter/Resources/res/values-in-v34/strings.xml index 9d375e022..7c8804397 100644 --- a/SafetyCenter/Resources/res/values-in-v34/strings.xml +++ b/SafetyCenter/Resources/res/values-in-v34/strings.xml @@ -24,9 +24,9 @@ <string name="health_connect_search_terms" msgid="4998970586245680829">"Health, Health Connect"</string> <string name="app_data_sharing_updates_title" msgid="7428862330643262588">"Pembaruan berbagi data untuk lokasi"</string> <string name="app_data_sharing_updates_search_terms" msgid="8414777373734245398">"Data, Berbagi data, Pembaruan berbagi data, Pembaruan berbagi data untuk lokasi, berbagi"</string> - <string name="advanced_title" msgid="6259362998269627310">"Setelan lainnya"</string> - <string name="more_settings_title" msgid="9033454654010697185">"Keamanan & privasi lainnya"</string> - <string name="more_settings_summary" msgid="7086620830002515710">"Isi otomatis, notifikasi, dan lainnya"</string> + <string name="advanced_title" msgid="6259362998269627310">"Setelan lain"</string> + <string name="more_settings_title" msgid="9033454654010697185">"Keamanan & privasi lain"</string> + <string name="more_settings_summary" msgid="7086620830002515710">"Isi otomatis, notifikasi, dan lain-lain"</string> <string name="more_settings_search_terms" msgid="1371913937610933955"></string> <string name="work_policy_title" msgid="915692932391542104">"Info kebijakan profil kerja Anda"</string> </resources> diff --git a/SafetyCenter/Resources/res/values-in-v35/strings.xml b/SafetyCenter/Resources/res/values-in-v35/strings.xml index 2e2554992..6e91010d7 100644 --- a/SafetyCenter/Resources/res/values-in-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-in-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Keamanan jaringan seluler"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Jenis jaringan, enkripsi, kontrol notifikasi"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Ruang Pribadi"</string> <string name="private_space_summary" msgid="529869826714610294">"Menyiapkan Ruang Pribadi, dan lainnya"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Ruang Pribadi"</string> diff --git a/SafetyCenter/Resources/res/values-is-v35/strings.xml b/SafetyCenter/Resources/res/values-is-v35/strings.xml index d74f29e63..94951412b 100644 --- a/SafetyCenter/Resources/res/values-is-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-is-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Öryggi farsímakerfis"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tegund netkerfis, dulkóðun, tilkynningastýringar"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Einkarými"</string> <string name="private_space_summary" msgid="529869826714610294">"Setja upp einkarými og fleira"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Einkarými"</string> diff --git a/SafetyCenter/Resources/res/values-it-v35/strings.xml b/SafetyCenter/Resources/res/values-it-v35/strings.xml index 26df4d265..5f98b4d0b 100644 --- a/SafetyCenter/Resources/res/values-it-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-it-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sicurezza rete mobile"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipo di rete, crittografia, controlli di notifica"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Spazio privato"</string> <string name="private_space_summary" msgid="529869826714610294">"Configura lo Spazio privato e altro ancora"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Spazio privato"</string> diff --git a/SafetyCenter/Resources/res/values-iw-v35/strings.xml b/SafetyCenter/Resources/res/values-iw-v35/strings.xml index edb3e2862..577721d76 100644 --- a/SafetyCenter/Resources/res/values-iw-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-iw-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"אבטחת הרשת הסלולרית"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"סוג הרשת, הצפנה, אמצעי בקרה של התראות"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"מרחב פרטי"</string> <string name="private_space_summary" msgid="529869826714610294">"הגדרת מרחב פרטי ועוד"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"מרחב פרטי"</string> diff --git a/SafetyCenter/Resources/res/values-ja-v35/strings.xml b/SafetyCenter/Resources/res/values-ja-v35/strings.xml index 4bd389ee3..8b5244ea5 100644 --- a/SafetyCenter/Resources/res/values-ja-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ja-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"モバイル ネットワークのセキュリティ"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ネットワークの種類、暗号化、通知の管理"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"プライベート スペース"</string> <string name="private_space_summary" msgid="529869826714610294">"プライベート スペースの設定、その他"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"プライベート スペース"</string> diff --git a/SafetyCenter/Resources/res/values-ja/strings.xml b/SafetyCenter/Resources/res/values-ja/strings.xml index 6e67998f4..b31b1690a 100644 --- a/SafetyCenter/Resources/res/values-ja/strings.xml +++ b/SafetyCenter/Resources/res/values-ja/strings.xml @@ -30,9 +30,9 @@ <string name="permission_usage_title" msgid="3633779688945350407">"プライバシー ダッシュボード"</string> <string name="permission_usage_summary" msgid="5323079206029964468">"権限を最近使用したアプリが表示されます"</string> <string name="permission_usage_search_terms" msgid="3852343592870257104">"プライバシー, プライバシー ダッシュボード"</string> - <string name="permission_manager_title" msgid="5277347862821255015">"権限マネージャー"</string> + <string name="permission_manager_title" msgid="5277347862821255015">"権限マネージャ"</string> <string name="permission_manager_summary" msgid="8099852107340970790">"アプリのデータアクセスを管理します"</string> - <string name="permission_manager_search_terms" msgid="2895147613099694722">"権限, 権限マネージャー"</string> + <string name="permission_manager_search_terms" msgid="2895147613099694722">"権限, 権限マネージャ"</string> <string name="privacy_controls_title" msgid="5322875777945432395">"プライバシー管理"</string> <string name="privacy_controls_summary" msgid="2402066941190435424">"マイク、カメラなどへのデバイス アクセスを管理します"</string> <string name="privacy_controls_search_terms" msgid="3774472175934304165">"プライバシー, プライバシー管理"</string> diff --git a/SafetyCenter/Resources/res/values-ka-v35/strings.xml b/SafetyCenter/Resources/res/values-ka-v35/strings.xml index 480f7e83c..479aa5f30 100644 --- a/SafetyCenter/Resources/res/values-ka-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ka-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"ფიჭური ქსელის უსაფრთხოება"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ქსელის ტიპი, დაშიფვრა, შეტყობინებების მართვის საშუალებები"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"პირადი სივრცე"</string> <string name="private_space_summary" msgid="529869826714610294">"დააყენეთ პირადი სივრცე და ა.შ."</string> <string name="private_space_search_terms" msgid="4820808478299116258">"პირადი სივრცე"</string> diff --git a/SafetyCenter/Resources/res/values-kk-v35/strings.xml b/SafetyCenter/Resources/res/values-kk-v35/strings.xml index f01ade9b8..cd667373c 100644 --- a/SafetyCenter/Resources/res/values-kk-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-kk-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Ұялы желі қауіпсіздігі"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Желі түрі, шифрлауды, хабарландыруды басқару элементтері"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Жеке бөлме"</string> <string name="private_space_summary" msgid="529869826714610294">"Жеке бөлмені реттеу және т.б."</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Жеке бөлме"</string> diff --git a/SafetyCenter/Resources/res/values-km-v35/strings.xml b/SafetyCenter/Resources/res/values-km-v35/strings.xml index 094bcb095..28324bd25 100644 --- a/SafetyCenter/Resources/res/values-km-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-km-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"សុវត្ថិភាពបណ្ដាញចល័ត"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ប្រភេទបណ្ដាញ ការអ៊ីនគ្រីប ការគ្រប់គ្រងការជូនដំណឹង"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"បន្ទប់ឯកជន"</string> <string name="private_space_summary" msgid="529869826714610294">"រៀបចំបន្ទប់ឯកជន និងធ្វើអ្វីៗជាច្រើនទៀត"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"បន្ទប់ឯកជន"</string> diff --git a/SafetyCenter/Resources/res/values-kn-v35/strings.xml b/SafetyCenter/Resources/res/values-kn-v35/strings.xml index 5260029a7..d86c54b2a 100644 --- a/SafetyCenter/Resources/res/values-kn-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-kn-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"ಸೆಲ್ಯುಲಾರ್ ನೆಟ್ವರ್ಕ್ ಭದ್ರತೆ"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ನೆಟ್ವರ್ಕ್ ಪ್ರಕಾರ, ಎನ್ಕ್ರಿಪ್ಶನ್, ನೋಟಿಫಿಕೇಶನ್ ಕಂಟ್ರೋಲ್ಗಳು"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"ಖಾಸಗಿ ಸ್ಪೇಸ್"</string> <string name="private_space_summary" msgid="529869826714610294">"ಖಾಸಗಿ ಸ್ಪೇಸ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಿ ಹಾಗೂ ಇನ್ನಷ್ಟನ್ನು ಮಾಡಿ"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"ಖಾಸಗಿ ಸ್ಪೇಸ್"</string> diff --git a/SafetyCenter/Resources/res/values-ko-v35/strings.xml b/SafetyCenter/Resources/res/values-ko-v35/strings.xml index 56fedb178..19900d3ad 100644 --- a/SafetyCenter/Resources/res/values-ko-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ko-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"셀룰러 네트워크 보안"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"네트워크 유형, 암호화, 알림 설정"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"비공개 스페이스"</string> <string name="private_space_summary" msgid="529869826714610294">"비공개 스페이스 설정 등"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"비공개 스페이스"</string> diff --git a/SafetyCenter/Resources/res/values-ky-v35/strings.xml b/SafetyCenter/Resources/res/values-ky-v35/strings.xml index 307c3a532..622f527b0 100644 --- a/SafetyCenter/Resources/res/values-ky-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ky-v35/strings.xml @@ -17,7 +17,10 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="private_space_title" msgid="6158245041481535879">"Жеке чөйрө"</string> - <string name="private_space_summary" msgid="529869826714610294">"Жеке чөйрөнү тууралоо жана башка нерселер"</string> - <string name="private_space_search_terms" msgid="4820808478299116258">"Жеке чөйрө"</string> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Мобилдик тармактын коопсуздугу"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Тармактын түрү, шифрлөө, билдирмелерди башкаруу элементтери"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> + <string name="private_space_title" msgid="6158245041481535879">"Жеке мейкиндик"</string> + <string name="private_space_summary" msgid="529869826714610294">"Жеке мейкиндикти тууралоо жана башка нерселер"</string> + <string name="private_space_search_terms" msgid="4820808478299116258">"Жеке мейкиндик"</string> </resources> diff --git a/SafetyCenter/Resources/res/values-lo-v35/strings.xml b/SafetyCenter/Resources/res/values-lo-v35/strings.xml index 381410da3..6de5852c2 100644 --- a/SafetyCenter/Resources/res/values-lo-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-lo-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"ຄວາມປອດໄພຂອງເຄືອຂ່າຍມືຖື"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ປະເພດເຄືອຂ່າຍ, ການເຂົ້າລະຫັດ, ການຄວບຄຸມການແຈ້ງເຕືອນ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"ພື້ນທີ່ສ່ວນຕົວ"</string> <string name="private_space_summary" msgid="529869826714610294">"ຕັ້ງຄ່າພື້ນທີ່ສ່ວນຕົວ ແລະ ອື່ນໆ"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"ພື້ນທີ່ສ່ວນຕົວ"</string> diff --git a/SafetyCenter/Resources/res/values-lt-v35/strings.xml b/SafetyCenter/Resources/res/values-lt-v35/strings.xml index b18eda435..6e28e6cea 100644 --- a/SafetyCenter/Resources/res/values-lt-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-lt-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobiliojo ryšio tinklo sauga"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tinklo tipas, šifruotė, pranešimų valdikliai"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privati erdvė"</string> <string name="private_space_summary" msgid="529869826714610294">"Nustatykite privačią erdvę ir atlikite kitų veiksmų"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privati erdvė"</string> diff --git a/SafetyCenter/Resources/res/values-lv-v35/strings.xml b/SafetyCenter/Resources/res/values-lv-v35/strings.xml index ffb1a7f4b..e39d2ea02 100644 --- a/SafetyCenter/Resources/res/values-lv-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-lv-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobilā tīkla drošība"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tīkla veids, šifrējums, paziņojumu vadīklas"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privātā mape"</string> <string name="private_space_summary" msgid="529869826714610294">"Privātās mapes iestatīšana un citas iespējas"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privātā mape"</string> diff --git a/SafetyCenter/Resources/res/values-mk-v35/strings.xml b/SafetyCenter/Resources/res/values-mk-v35/strings.xml index 879a67555..5ecb3db51 100644 --- a/SafetyCenter/Resources/res/values-mk-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-mk-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Безбедност на мобилната мрежа"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Контроли за известувања на тип мрежа, шифрирање"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Приватен простор"</string> <string name="private_space_summary" msgid="529869826714610294">"Поставување „Приватен простор“ и друго"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Приватен простор"</string> diff --git a/SafetyCenter/Resources/res/values-ml-v35/strings.xml b/SafetyCenter/Resources/res/values-ml-v35/strings.xml index c6e728c4f..2923b81c7 100644 --- a/SafetyCenter/Resources/res/values-ml-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ml-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"സെല്ലുലാർ നെറ്റ്വർക്ക് സുരക്ഷ"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"നെറ്റ്വർക്ക് തരം, എൻക്രിപ്ഷൻ, അറിയിപ്പ് നിയന്ത്രണങ്ങൾ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"സ്വകാര്യ Space"</string> <string name="private_space_summary" msgid="529869826714610294">"സ്വകാര്യ Space സജ്ജീകരിക്കുകയും മറ്റും ചെയ്യൂ"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"സ്വകാര്യ Space"</string> diff --git a/SafetyCenter/Resources/res/values-mn-v35/strings.xml b/SafetyCenter/Resources/res/values-mn-v35/strings.xml index 290462d37..1ec4acfc4 100644 --- a/SafetyCenter/Resources/res/values-mn-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-mn-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Үүрэн холбооны сүлжээний аюулгүй байдал"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Сүлжээний төрөл, шифрлэлт, мэдэгдлийн тохиргоо"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Хувийн орон зай"</string> <string name="private_space_summary" msgid="529869826714610294">"Хувийн орон зай тохируулах болон илүү ихийг хийх"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Хувийн орон зай"</string> diff --git a/SafetyCenter/Resources/res/values-mr-v35/strings.xml b/SafetyCenter/Resources/res/values-mr-v35/strings.xml index 0ec596e1c..768af9303 100644 --- a/SafetyCenter/Resources/res/values-mr-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-mr-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"मोबाइल नेटवर्कची सुरक्षा"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"नेटवर्क प्रकार, एन्क्रिप्शन, सूचना नियंत्रणे"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"खाजगी स्पेस"</string> <string name="private_space_summary" msgid="529869826714610294">"खाजगी स्पेस आणि आणखी बरेच काही सेट करा"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"खाजगी स्पेस"</string> diff --git a/SafetyCenter/Resources/res/values-ms-v35/strings.xml b/SafetyCenter/Resources/res/values-ms-v35/strings.xml index b0694a876..a15f04b43 100644 --- a/SafetyCenter/Resources/res/values-ms-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ms-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Keselamatan rangkaian selular"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Jenis rangkaian, penyulitan, kawalan pemberitahuan"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Ruang Peribadi"</string> <string name="private_space_summary" msgid="529869826714610294">"Sediakan Ruang Peribadi dan pelbagai lagi"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Ruang Peribadi"</string> diff --git a/SafetyCenter/Resources/res/values-my-v35/strings.xml b/SafetyCenter/Resources/res/values-my-v35/strings.xml index 4141dd6ac..dd6a9cdda 100644 --- a/SafetyCenter/Resources/res/values-my-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-my-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"ဆယ်လူလာကွန်ရက် လုံခြုံရေး"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ကွန်ရက်အမျိုးအစား၊ အသွင်ဝှက်ခြင်း၊ အကြောင်းကြားချက် သတ်မှတ်ချက်များ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"သီးသန့်ချတ်ခန်း"</string> <string name="private_space_summary" msgid="529869826714610294">"သီးသန့်ချတ်ခန်း စသည်တို့ကို စနစ်ထည့်သွင်းသည်"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"သီးသန့်ချတ်ခန်း"</string> diff --git a/SafetyCenter/Resources/res/values-nb-v35/strings.xml b/SafetyCenter/Resources/res/values-nb-v35/strings.xml index 5575b4d1f..ab403952c 100644 --- a/SafetyCenter/Resources/res/values-nb-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-nb-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Sikkerhet for mobilnettverk"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Nettverkstype, kryptering, varselskontroller"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Private Space"</string> <string name="private_space_summary" msgid="529869826714610294">"Konfigurer Private Space med mer"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Private Space"</string> diff --git a/SafetyCenter/Resources/res/values-ne-v35/strings.xml b/SafetyCenter/Resources/res/values-ne-v35/strings.xml index 1d96a0c82..4c79b5b10 100644 --- a/SafetyCenter/Resources/res/values-ne-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ne-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"मोबाइल नेटवर्कको सुरक्षा"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"नेटवर्कको प्रकार, इन्क्रिप्सन, सूचनाका सेटिङ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"निजी स्पेस"</string> <string name="private_space_summary" msgid="529869826714610294">"निजी स्पेस सेटअप गर्नुहोस् र अन्य कार्यहरू गर्नुहोस्"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"निजी स्पेस"</string> diff --git a/SafetyCenter/Resources/res/values-nl-v35/strings.xml b/SafetyCenter/Resources/res/values-nl-v35/strings.xml index dc927ade3..ac2beee11 100644 --- a/SafetyCenter/Resources/res/values-nl-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-nl-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Beveiliging van mobiele netwerken"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Netwerktype, versleuteling, beheeropties voor meldingen"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privéruimte"</string> <string name="private_space_summary" msgid="529869826714610294">"Privéruimte instellen en meer"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privéruimte"</string> diff --git a/SafetyCenter/Resources/res/values-or-v35/strings.xml b/SafetyCenter/Resources/res/values-or-v35/strings.xml index 85c4fa73c..5e546c5db 100644 --- a/SafetyCenter/Resources/res/values-or-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-or-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"ସେଲୁଲାର ନେଟୱାର୍କ ସୁରକ୍ଷା"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ନେଟୱାର୍କ ପ୍ରକାର, ଏନକ୍ରିପସନ, ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string> <string name="private_space_summary" msgid="529869826714610294">"ପ୍ରାଇଭେଟ ସ୍ପେସ ଏବଂ ଆହୁରି ଅନେକ କିଛି ସେଟଅପ କରନ୍ତୁ"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string> diff --git a/SafetyCenter/Resources/res/values-pa-v35/strings.xml b/SafetyCenter/Resources/res/values-pa-v35/strings.xml index f1e2dd714..985f3b144 100644 --- a/SafetyCenter/Resources/res/values-pa-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-pa-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"ਸੈਲਿਊਲਰ ਨੈੱਟਵਰਕ ਸੁਰੱਖਿਆ"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ਨੈੱਟਵਰਕ ਦੀ ਕਿਸਮ, ਇਨਕ੍ਰਿਪਸ਼ਨ, ਸੂਚਨਾ ਕੰਟਰੋਲ"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"ਨਿੱਜੀ ਸਪੇਸ"</string> <string name="private_space_summary" msgid="529869826714610294">"ਨਿੱਜੀ ਸਪੇਸ ਦਾ ਸੈੱਟਅੱਪ ਅਤੇ ਹੋਰ ਕੰਮ ਕਰੋ"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"ਨਿੱਜੀ ਸਪੇਸ"</string> diff --git a/SafetyCenter/Resources/res/values-pl-v35/strings.xml b/SafetyCenter/Resources/res/values-pl-v35/strings.xml index 56c410a05..0d6747501 100644 --- a/SafetyCenter/Resources/res/values-pl-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-pl-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Zabezpieczenia sieci komórkowej"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Typ sieci, szyfrowanie, ustawienia powiadomień"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Obszar prywatny"</string> <string name="private_space_summary" msgid="529869826714610294">"Skonfiguruj obszar prywatny i inne ustawienia"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Obszar prywatny"</string> diff --git a/SafetyCenter/Resources/res/values-pt-rBR-v35/strings.xml b/SafetyCenter/Resources/res/values-pt-rBR-v35/strings.xml index ef0c3c738..10178f3a2 100644 --- a/SafetyCenter/Resources/res/values-pt-rBR-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-pt-rBR-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Segurança da rede celular"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipo de rede, criptografia, controles de notificação"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espaço particular"</string> <string name="private_space_summary" msgid="529869826714610294">"Configurar Espaço particular e mais"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espaço particular"</string> diff --git a/SafetyCenter/Resources/res/values-pt-rPT-v35/strings.xml b/SafetyCenter/Resources/res/values-pt-rPT-v35/strings.xml index 6e397ccf0..9456eb00c 100644 --- a/SafetyCenter/Resources/res/values-pt-rPT-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-pt-rPT-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Segurança da rede móvel"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipo de rede, encriptação, controlos de notificação"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espaço privado"</string> <string name="private_space_summary" msgid="529869826714610294">"Configure o espaço privado e muito mais"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espaço privado"</string> diff --git a/SafetyCenter/Resources/res/values-pt-v35/strings.xml b/SafetyCenter/Resources/res/values-pt-v35/strings.xml index ef0c3c738..10178f3a2 100644 --- a/SafetyCenter/Resources/res/values-pt-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-pt-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Segurança da rede celular"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipo de rede, criptografia, controles de notificação"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Espaço particular"</string> <string name="private_space_summary" msgid="529869826714610294">"Configurar Espaço particular e mais"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Espaço particular"</string> diff --git a/SafetyCenter/Resources/res/values-ro-v35/strings.xml b/SafetyCenter/Resources/res/values-ro-v35/strings.xml index 5884075bf..96a80f9d3 100644 --- a/SafetyCenter/Resources/res/values-ro-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ro-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Securitatea rețelei de date mobile"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tipul de rețea, criptarea, comenzile pentru notificări"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Spațiu privat"</string> <string name="private_space_summary" msgid="529869826714610294">"Configurează Spațiul privat și altele"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Spațiu privat"</string> diff --git a/SafetyCenter/Resources/res/values-ru-v35/strings.xml b/SafetyCenter/Resources/res/values-ru-v35/strings.xml index 29a17d7a9..89e6939a5 100644 --- a/SafetyCenter/Resources/res/values-ru-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ru-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Безопасность мобильной сети"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Тип сети, шифрование, управление уведомлениями"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Личное пространство"</string> <string name="private_space_summary" msgid="529869826714610294">"Настройка личного пространства и не только"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Личное пространство"</string> diff --git a/SafetyCenter/Resources/res/values-si-v35/strings.xml b/SafetyCenter/Resources/res/values-si-v35/strings.xml index c3605e2a1..8e8b48460 100644 --- a/SafetyCenter/Resources/res/values-si-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-si-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"සෙලියුලර් ජාල ආරක්ෂාව"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ජාල වර්ගය, සංකේතනය, දැනුම්දීම් පාලන"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"පෞද්ගලික ඉඩ"</string> <string name="private_space_summary" msgid="529869826714610294">"පෞද්ගලික ඉඩ, සහ තවත් දේ පිහිටුවන්න"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"පෞද්ගලික ඉඩ"</string> diff --git a/SafetyCenter/Resources/res/values-sk-v35/strings.xml b/SafetyCenter/Resources/res/values-sk-v35/strings.xml index bed329c6b..fbd935881 100644 --- a/SafetyCenter/Resources/res/values-sk-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-sk-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Zabezpečenie mobilnej siete"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Ovládanie typu siete, šifrovania a upozornení"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Súkromný priestor"</string> <string name="private_space_summary" msgid="529869826714610294">"Nastavte súkromný priestor a ďalšie možnosti"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Súkromný priestor"</string> diff --git a/SafetyCenter/Resources/res/values-sl-v35/strings.xml b/SafetyCenter/Resources/res/values-sl-v35/strings.xml index aa7a10258..317b8eb36 100644 --- a/SafetyCenter/Resources/res/values-sl-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-sl-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Varnost mobilnega omrežja"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Vrsta omrežja, šifriranje, kontrolniki obvestil"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Zasebni prostor"</string> <string name="private_space_summary" msgid="529869826714610294">"Nastavitev zasebnega prostora in drugo"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Zasebni prostor"</string> diff --git a/SafetyCenter/Resources/res/values-sq-v35/strings.xml b/SafetyCenter/Resources/res/values-sq-v35/strings.xml index 63c642f89..067302507 100644 --- a/SafetyCenter/Resources/res/values-sq-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-sq-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Siguria e rrjetit celular"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Lloji i rrjetit, enkriptimi, kontrollet e njoftimeve"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Hapësira private"</string> <string name="private_space_summary" msgid="529869826714610294">"Konfiguro \"Hapësirën private\" dhe të tjera"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Hapësira private"</string> diff --git a/SafetyCenter/Resources/res/values-sr-v35/strings.xml b/SafetyCenter/Resources/res/values-sr-v35/strings.xml index b2349b10a..66ee14e01 100644 --- a/SafetyCenter/Resources/res/values-sr-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-sr-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Безбедност мобилне мреже"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Тип мреже, шифровање, контроле обавештења"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Приватни простор"</string> <string name="private_space_summary" msgid="529869826714610294">"Подесите приватни простор и друго"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Приватни простор"</string> diff --git a/SafetyCenter/Resources/res/values-sr/strings.xml b/SafetyCenter/Resources/res/values-sr/strings.xml index 2cd42d24c..af0f51727 100644 --- a/SafetyCenter/Resources/res/values-sr/strings.xml +++ b/SafetyCenter/Resources/res/values-sr/strings.xml @@ -22,7 +22,7 @@ <string name="lock_screen_sources_summary" msgid="7220439741282516496"></string> <string name="lock_screen_title" msgid="4069104894527169877">"Откључавање екрана"</string> <string name="lock_screen_summary_disabled" msgid="354071230916616692">"Још нема информација"</string> - <string name="lock_screen_search_terms" msgid="2678486357779794826">"закључавање уређаја, закључавање екрана, закључани екран, лозинка, PIN, шаблон"</string> + <string name="lock_screen_search_terms" msgid="2678486357779794826">"закључавање уређаја, откључавање екрана, закључани екран, лозинка, PIN, шаблон"</string> <string name="biometrics_title" msgid="5859504610285212938">"Биометрија"</string> <string name="biometrics_search_terms" msgid="6040319118762671981">"отисак прста, прст, додај отисак прста, откључавање лицем, лице"</string> <string name="privacy_sources_title" msgid="4061110826457365957">"Приватност"</string> diff --git a/SafetyCenter/Resources/res/values-sv-v35/strings.xml b/SafetyCenter/Resources/res/values-sv-v35/strings.xml index 85e0e6a7d..1fa3ff62a 100644 --- a/SafetyCenter/Resources/res/values-sv-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-sv-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Säkerhet för mobilnätverk"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Nätverkstyp, kryptering, aviseringsinställningar"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Privat rum"</string> <string name="private_space_summary" msgid="529869826714610294">"Ställ in privat rum med mera"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Privat rum"</string> diff --git a/SafetyCenter/Resources/res/values-sw-v35/strings.xml b/SafetyCenter/Resources/res/values-sw-v35/strings.xml index 9ef8839b5..3ddbf11cd 100644 --- a/SafetyCenter/Resources/res/values-sw-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-sw-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Usalama wa mtandao wa simu"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Aina ya mtandao, usimbaji fiche, vidhibiti vya arifa"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Nafasi ya Faragha"</string> <string name="private_space_summary" msgid="529869826714610294">"Weka mipangilio ya Nafasi ya Faragha na zaidi"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Nafasi ya Faragha"</string> diff --git a/SafetyCenter/Resources/res/values-ta-v35/strings.xml b/SafetyCenter/Resources/res/values-ta-v35/strings.xml index 73591d1b0..ca7ac1f84 100644 --- a/SafetyCenter/Resources/res/values-ta-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ta-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"மொபைல் நெட்வொர்க் பாதுகாப்பு"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"நெட்வொர்க் வகை, என்க்ரிப்ஷன், அறிவிப்புக் கட்டுப்பாடுகள்"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"தனிப்பட்ட சேமிப்பிடம்"</string> <string name="private_space_summary" msgid="529869826714610294">"தனிப்பட்ட சேமிப்பிடத்தை அமைக்கலாம் மற்றும் பலவற்றைச் செய்யலாம்"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"தனிப்பட்ட சேமிப்பிடம்"</string> diff --git a/SafetyCenter/Resources/res/values-te-v35/strings.xml b/SafetyCenter/Resources/res/values-te-v35/strings.xml index ffccea816..08691b56a 100644 --- a/SafetyCenter/Resources/res/values-te-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-te-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"సెల్యులర్ నెట్వర్క్ సెక్యూరిటీ"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"నెట్వర్క్ రకం, ఎన్క్రిప్షన్, నోటిఫికేషన్ కంట్రోల్స్"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"ప్రైవేట్ స్పేస్"</string> <string name="private_space_summary" msgid="529869826714610294">"ప్రైవేట్ స్పేస్ను సెటప్ చేయండి, మరెన్నింటినో చేయండి"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"ప్రైవేట్ స్పేస్"</string> diff --git a/SafetyCenter/Resources/res/values-th-v35/strings.xml b/SafetyCenter/Resources/res/values-th-v35/strings.xml index f16443413..dd9796b66 100644 --- a/SafetyCenter/Resources/res/values-th-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-th-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"การรักษาความปลอดภัยของเครือข่ายมือถือ"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"ประเภทเครือข่าย การเข้ารหัส ส่วนควบคุมการแจ้งเตือน"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"พื้นที่ส่วนตัว"</string> <string name="private_space_summary" msgid="529869826714610294">"ตั้งค่าพื้นที่ส่วนตัวและอื่นๆ"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"พื้นที่ส่วนตัว"</string> diff --git a/SafetyCenter/Resources/res/values-tl-v35/strings.xml b/SafetyCenter/Resources/res/values-tl-v35/strings.xml index f28f2ba45..855fbee18 100644 --- a/SafetyCenter/Resources/res/values-tl-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-tl-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Seguridad ng cellular network"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Network type, pag-encrypt, mga kontrol sa notification"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Pribadong Space"</string> <string name="private_space_summary" msgid="529869826714610294">"I-set up ang Pribadong Space, at higit pa"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Pribadong Space"</string> diff --git a/SafetyCenter/Resources/res/values-tr-v35/strings.xml b/SafetyCenter/Resources/res/values-tr-v35/strings.xml index 26977f3d3..670836e65 100644 --- a/SafetyCenter/Resources/res/values-tr-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-tr-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Hücresel ağ güvenliği"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Ağ türü, şifreleme, bildirim kontrolleri"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Gizli Alan"</string> <string name="private_space_summary" msgid="529869826714610294">"Gizli alan yapılandırma ve daha fazlası"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Gizli Alan"</string> diff --git a/SafetyCenter/Resources/res/values-uk-v35/strings.xml b/SafetyCenter/Resources/res/values-uk-v35/strings.xml index 4478750ab..70ac6516a 100644 --- a/SafetyCenter/Resources/res/values-uk-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-uk-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Безпека мобільної мережі"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Тип мережі, шифрування, налаштування сповіщень"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Приватний простір"</string> <string name="private_space_summary" msgid="529869826714610294">"Налаштуйте приватний простір тощо"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Приватний простір"</string> diff --git a/SafetyCenter/Resources/res/values-ur-v35/strings.xml b/SafetyCenter/Resources/res/values-ur-v35/strings.xml index c506baa97..d9b81b1ce 100644 --- a/SafetyCenter/Resources/res/values-ur-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-ur-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"سیلولر نیٹ ورک سیکیورٹی"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"نیٹ ورک کی قسم، مرموز کاری، نوٹیفکیشن کنٹرولز"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"نجی اسپیس"</string> <string name="private_space_summary" msgid="529869826714610294">"نجی اسپیس اور بھی بہت کچھ سیٹ اپ کریں"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"نجی اسپیس"</string> diff --git a/SafetyCenter/Resources/res/values-uz-v35/strings.xml b/SafetyCenter/Resources/res/values-uz-v35/strings.xml index d8813cc82..bd6adac69 100644 --- a/SafetyCenter/Resources/res/values-uz-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-uz-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Mobil tarmoq xavfsizligi"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Tarmoq turi, shifrlash, bildirishnomalar boshqaruvi"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Maxfiy joy"</string> <string name="private_space_summary" msgid="529869826714610294">"Maxfiy joyni sozlash"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Maxfiy joy"</string> diff --git a/SafetyCenter/Resources/res/values-v35/strings.xml b/SafetyCenter/Resources/res/values-v35/strings.xml index 620dc8d60..bdbc4b648 100644 --- a/SafetyCenter/Resources/res/values-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-v35/strings.xml @@ -16,6 +16,13 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Cellular Network Security --> + <string name="cellular_network_security_title" description="The title of the group of safety settings relating to cellular network security">Cellular network security</string> + <string name="cellular_network_security_summary" description="The summary of the group of safety settings relating to cellular network security, which describes the group contents">Network type, encryption, notification controls</string> + + <!-- Device unlock --> + <string name="biometrics_title_for_private_profile" description="The default title of the setting for managing biometric options on the device for private space"><!-- Empty placeholder--></string> + <!-- More settings --> <string name="private_space_title" description="The title of the entry for Private Space">Private Space</string> <string name="private_space_summary" description="The summary of the entry for Private Space settings, which describes the page contents">Setup Private Space, and more</string> diff --git a/SafetyCenter/Resources/res/values-vi-v35/strings.xml b/SafetyCenter/Resources/res/values-vi-v35/strings.xml index b37e81085..e067e7585 100644 --- a/SafetyCenter/Resources/res/values-vi-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-vi-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Chế độ bảo mật mạng di động"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Loại mạng, quy trình mã hoá, quyền kiểm soát thông báo"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Không gian riêng tư"</string> <string name="private_space_summary" msgid="529869826714610294">"Thiết lập Không gian riêng tư và các tính năng khác"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Không gian riêng tư"</string> diff --git a/SafetyCenter/Resources/res/values-zh-rCN-v34/strings.xml b/SafetyCenter/Resources/res/values-zh-rCN-v34/strings.xml index 5b8a8fe8d..da468fa0e 100644 --- a/SafetyCenter/Resources/res/values-zh-rCN-v34/strings.xml +++ b/SafetyCenter/Resources/res/values-zh-rCN-v34/strings.xml @@ -20,9 +20,9 @@ <string name="lock_screen_sources_title" msgid="5493678510117489865">"设备解锁"</string> <string name="biometrics_title_for_work" msgid="1842284049407771568">"适用于工作应用的生物识别"</string> <string name="privacy_sources_summary" msgid="4083646673569677049">"权限、信息中心和控件"</string> - <string name="health_connect_title" msgid="8318152190040327804">"Health Connect"</string> - <string name="health_connect_search_terms" msgid="4998970586245680829">"健康, Health, Health Connect"</string> - <string name="app_data_sharing_updates_title" msgid="7428862330643262588">"位置数据分享方面的更新"</string> + <string name="health_connect_title" msgid="8318152190040327804">"健康数据共享"</string> + <string name="health_connect_search_terms" msgid="4998970586245680829">"健康, 健康数据共享, Health, Health Connect"</string> + <string name="app_data_sharing_updates_title" msgid="7428862330643262588">"位置数据共享方面的更新"</string> <string name="app_data_sharing_updates_search_terms" msgid="8414777373734245398">"数据, 数据分享, 数据分享方面的更新, 位置数据分享方面的更新, 分享, Data, Data sharing, Data sharing updates, Data sharing updates for location, sharing"</string> <string name="advanced_title" msgid="6259362998269627310">"其他设置"</string> <string name="more_settings_title" msgid="9033454654010697185">"更多安全和隐私设置"</string> diff --git a/SafetyCenter/Resources/res/values-zh-rCN-v35/strings.xml b/SafetyCenter/Resources/res/values-zh-rCN-v35/strings.xml index e13cffd8a..a613a9e13 100644 --- a/SafetyCenter/Resources/res/values-zh-rCN-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-zh-rCN-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"移动网络安全性"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"网络类型、加密、通知控件"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"私密空间"</string> <string name="private_space_summary" msgid="529869826714610294">"设置私密空间等"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"私密空间"</string> diff --git a/SafetyCenter/Resources/res/values-zh-rHK-v34/strings.xml b/SafetyCenter/Resources/res/values-zh-rHK-v34/strings.xml index a11abbde1..c850335ad 100644 --- a/SafetyCenter/Resources/res/values-zh-rHK-v34/strings.xml +++ b/SafetyCenter/Resources/res/values-zh-rHK-v34/strings.xml @@ -21,7 +21,7 @@ <string name="biometrics_title_for_work" msgid="1842284049407771568">"用於工作應用程式的生物識別選項"</string> <string name="privacy_sources_summary" msgid="4083646673569677049">"權限、資訊主頁、控制項"</string> <string name="health_connect_title" msgid="8318152190040327804">"Health Connect"</string> - <string name="health_connect_search_terms" msgid="4998970586245680829">"健康, Health Connect"</string> + <string name="health_connect_search_terms" msgid="4998970586245680829">"健康, 健康資料同步"</string> <string name="app_data_sharing_updates_title" msgid="7428862330643262588">"位置資料分享更新"</string> <string name="app_data_sharing_updates_search_terms" msgid="8414777373734245398">"資料, 資料分享, 資料分享更新, 位置資料分享更新, 分享"</string> <string name="advanced_title" msgid="6259362998269627310">"其他設定"</string> diff --git a/SafetyCenter/Resources/res/values-zh-rHK-v35/strings.xml b/SafetyCenter/Resources/res/values-zh-rHK-v35/strings.xml index 996efe5f3..f46f3b083 100644 --- a/SafetyCenter/Resources/res/values-zh-rHK-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-zh-rHK-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"流動網絡安全性"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"網絡類型、加密、通知控制項"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"私人空間"</string> <string name="private_space_summary" msgid="529869826714610294">"設定「私人空間」等項目"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"私人空間"</string> diff --git a/SafetyCenter/Resources/res/values-zh-rTW-v34/strings.xml b/SafetyCenter/Resources/res/values-zh-rTW-v34/strings.xml index 288a0566c..54bbf0f1c 100644 --- a/SafetyCenter/Resources/res/values-zh-rTW-v34/strings.xml +++ b/SafetyCenter/Resources/res/values-zh-rTW-v34/strings.xml @@ -20,9 +20,9 @@ <string name="lock_screen_sources_title" msgid="5493678510117489865">"裝置解鎖"</string> <string name="biometrics_title_for_work" msgid="1842284049407771568">"工作應用程式的生物特徵辨識選項"</string> <string name="privacy_sources_summary" msgid="4083646673569677049">"權限、資訊主頁、控制選項"</string> - <string name="health_connect_title" msgid="8318152190040327804">"Health Connect"</string> - <string name="health_connect_search_terms" msgid="4998970586245680829">"健康、Health Connect"</string> - <string name="app_data_sharing_updates_title" msgid="7428862330643262588">"位置資料分享更新"</string> + <string name="health_connect_title" msgid="8318152190040327804">"健康資料同步"</string> + <string name="health_connect_search_terms" msgid="4998970586245680829">"健康, 健康資料同步"</string> + <string name="app_data_sharing_updates_title" msgid="7428862330643262588">"位置資料共用方式更新"</string> <string name="app_data_sharing_updates_search_terms" msgid="8414777373734245398">"資料, 資料分享, 資料分享更新, 位置資料分享更新, 分享"</string> <string name="advanced_title" msgid="6259362998269627310">"其他設定"</string> <string name="more_settings_title" msgid="9033454654010697185">"其他安全性和隱私權設定"</string> diff --git a/SafetyCenter/Resources/res/values-zh-rTW-v35/strings.xml b/SafetyCenter/Resources/res/values-zh-rTW-v35/strings.xml index 36f68819d..d9b6a4ff6 100644 --- a/SafetyCenter/Resources/res/values-zh-rTW-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-zh-rTW-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"行動網路安全性"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"網路類型、加密、通知控制選項"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"私人空間"</string> <string name="private_space_summary" msgid="529869826714610294">"設定私人空間等項目"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"私人空間"</string> diff --git a/SafetyCenter/Resources/res/values-zu-v35/strings.xml b/SafetyCenter/Resources/res/values-zu-v35/strings.xml index 659e1b58d..237b2974f 100644 --- a/SafetyCenter/Resources/res/values-zu-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-zu-v35/strings.xml @@ -17,6 +17,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="cellular_network_security_title" msgid="2986431282931510973">"Ukuphepha kwenethiwekhi yeselula"</string> + <string name="cellular_network_security_summary" msgid="7319307247487475572">"Uhlobo lwenethiwekhi, ukubethela, izilawuli zezaziso"</string> + <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="private_space_title" msgid="6158245041481535879">"Isikhala Esiyimfihlo"</string> <string name="private_space_summary" msgid="529869826714610294">"Setha Isikhala Esiyimfihlo, nokunye"</string> <string name="private_space_search_terms" msgid="4820808478299116258">"Isikhala Esiyimfihlo"</string> diff --git a/SafetyCenter/Resources/shared_res/values-ar/strings.xml b/SafetyCenter/Resources/shared_res/values-ar/strings.xml index 49e16c39c..214844da1 100644 --- a/SafetyCenter/Resources/shared_res/values-ar/strings.xml +++ b/SafetyCenter/Resources/shared_res/values-ar/strings.xml @@ -20,7 +20,7 @@ <string name="scanning_title" msgid="5424849039854311398">"جارٍ الفحص"</string> <string name="loading_summary" msgid="3740846439782713910">"جارٍ التحقّق من إعدادات الجهاز…"</string> <string name="overall_severity_level_ok_title" msgid="2041250138727564565">"كل شيء على ما يرام"</string> - <string name="overall_severity_level_ok_summary" msgid="383626536912856690">"لم يتم رصد أي مشاكل."</string> + <string name="overall_severity_level_ok_summary" msgid="383626536912856690">"لم يتم رصد أي مشاكل"</string> <string name="overall_severity_level_tip_summary" msgid="1935765582243024999">"{count,plural, =1{الاطّلاع على اقتراح}zero{الاطّلاع على اقتراحات}two{الاطّلاع على اقتراحَين}few{الاطّلاع على اقتراحات}many{الاطّلاع على اقتراحات}other{الاطّلاع على اقتراحات}}"</string> <string name="overall_severity_level_action_taken_summary" msgid="8064091657855656545">"{count,plural, =1{الإجراء الذي تم اتخاذه}zero{الإجراءات التي تم اتخاذها}two{الإجراءان اللذان تم اتخاذهما}few{الإجراءات التي تم اتخاذها}many{الإجراءات التي تم اتخاذها}other{الإجراءات التي تم اتخاذها}}"</string> <string name="overall_severity_level_ok_review_title" msgid="1494321117696765360">"مراجعة الإعدادات"</string> diff --git a/SafetyCenter/Resources/shared_res/values-ca/strings.xml b/SafetyCenter/Resources/shared_res/values-ca/strings.xml index 640a723c1..a2d8b0f35 100644 --- a/SafetyCenter/Resources/shared_res/values-ca/strings.xml +++ b/SafetyCenter/Resources/shared_res/values-ca/strings.xml @@ -26,7 +26,7 @@ <string name="overall_severity_level_ok_review_title" msgid="1494321117696765360">"Revisa la configuració"</string> <string name="overall_severity_level_ok_review_summary" msgid="7743619617413076275">"Comprova la llista d\'opcions de configuració"</string> <string name="overall_severity_level_device_recommendation_title" msgid="5250040236433061827">"El dispositiu pot estar en perill"</string> - <string name="overall_severity_level_critical_device_warning_title" msgid="5901771721834272596">"Dispositiu en perill"</string> + <string name="overall_severity_level_critical_device_warning_title" msgid="5901771721834272596">"El dispositiu està en perill"</string> <string name="overall_severity_level_data_recommendation_title" msgid="1424269714861655302">"Les dades poden estar en perill"</string> <string name="overall_severity_level_critical_data_warning_title" msgid="1012704126634698604">"Les dades estan en perill"</string> <string name="overall_severity_level_passwords_recommendation_title" msgid="8625105570296877719">"Contrasenyes en perill (antigues)"</string> diff --git a/SafetyCenter/Resources/shared_res/values-kk/strings.xml b/SafetyCenter/Resources/shared_res/values-kk/strings.xml index 9226d4fcb..386a0d465 100644 --- a/SafetyCenter/Resources/shared_res/values-kk/strings.xml +++ b/SafetyCenter/Resources/shared_res/values-kk/strings.xml @@ -25,7 +25,7 @@ <string name="overall_severity_level_action_taken_summary" msgid="8064091657855656545">"{count,plural, =1{Әрекет жасалды.}other{Әрекеттер жасалды.}}"</string> <string name="overall_severity_level_ok_review_title" msgid="1494321117696765360">"Параметрлерді тексерy"</string> <string name="overall_severity_level_ok_review_summary" msgid="7743619617413076275">"Параметрлер тізімін тексеріңіз."</string> - <string name="overall_severity_level_device_recommendation_title" msgid="5250040236433061827">"Құрылғыға қауіп төнген болуы мүмкін"</string> + <string name="overall_severity_level_device_recommendation_title" msgid="5250040236433061827">"Құрылғыға қауіп төнген сияқты"</string> <string name="overall_severity_level_critical_device_warning_title" msgid="5901771721834272596">"Құрылғыға қауіп төніп тұр"</string> <string name="overall_severity_level_data_recommendation_title" msgid="1424269714861655302">"Деректерге қауіп төнген сияқты"</string> <string name="overall_severity_level_critical_data_warning_title" msgid="1012704126634698604">"Деректерге қауіп төніп тұр"</string> diff --git a/SafetyCenter/Resources/shared_res/values-nl/strings.xml b/SafetyCenter/Resources/shared_res/values-nl/strings.xml index ab8edda5d..4b1000112 100644 --- a/SafetyCenter/Resources/shared_res/values-nl/strings.xml +++ b/SafetyCenter/Resources/shared_res/values-nl/strings.xml @@ -18,7 +18,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="scanning_title" msgid="5424849039854311398">"Scannen"</string> - <string name="loading_summary" msgid="3740846439782713910">"Apparaatinstellingen checken…"</string> + <string name="loading_summary" msgid="3740846439782713910">"Apparaatinstellingen controleren…"</string> <string name="overall_severity_level_ok_title" msgid="2041250138727564565">"Dat ziet er goed uit"</string> <string name="overall_severity_level_ok_summary" msgid="383626536912856690">"Geen problemen gevonden"</string> <string name="overall_severity_level_tip_summary" msgid="1935765582243024999">"{count,plural, =1{Aanbeveling bekijken}other{Aanbevelingen bekijken}}"</string> diff --git a/SafetyCenter/Resources/shared_res/values-pa/strings.xml b/SafetyCenter/Resources/shared_res/values-pa/strings.xml index 54aad5cbb..8b17156df 100644 --- a/SafetyCenter/Resources/shared_res/values-pa/strings.xml +++ b/SafetyCenter/Resources/shared_res/values-pa/strings.xml @@ -39,7 +39,7 @@ <string name="overall_severity_level_critical_account_warning_title" msgid="1913235490583842004">"ਖਾਤਾ ਜੋਖਮ ਵਿੱਚ ਹੈ"</string> <string name="overall_severity_n_alerts_summary" msgid="3262010942295408403">"{count,plural, =1{ਅਲਰਟ ਦੇਖੋ}one{ਅਲਰਟ ਦੇਖੋ}other{ਅਲਰਟ ਦੇਖੋ}}"</string> <string name="redirecting_error" msgid="8146983632878233202">"ਪੰਨਾ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ"</string> - <string name="resolving_action_error" msgid="371968886143262375">"ਸੁਚੇਤਨਾ ਦਾ ਹੱਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string> + <string name="resolving_action_error" msgid="371968886143262375">"ਅਲਰਟ ਦਾ ਹੱਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string> <string name="refresh_error" msgid="656062128422446177">"{count,plural, =1{ਸੈਟਿੰਗ ਦੀ ਜਾਂਚ ਨਹੀਂ ਕਰ ਸਕੇ}one{ਸੈਟਿੰਗ ਦੀ ਜਾਂਚ ਨਹੀਂ ਕਰ ਸਕੇ}other{ਸੈਟਿੰਗਾਂ ਦੀ ਜਾਂਚ ਨਹੀਂ ਕਰ ਸਕੇ}}"</string> <string name="work_profile_paused" msgid="7037400224040869079">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ"</string> <string name="group_unknown_summary" msgid="6951386960814105641">"ਅਜੇ ਕੋਈ ਜਾਣਕਾਰੀ ਨਹੀਂ ਹੈ"</string> diff --git a/SafetyCenter/Resources/shared_res/values-ru/strings.xml b/SafetyCenter/Resources/shared_res/values-ru/strings.xml index b72d9b0f0..7e8e9f822 100644 --- a/SafetyCenter/Resources/shared_res/values-ru/strings.xml +++ b/SafetyCenter/Resources/shared_res/values-ru/strings.xml @@ -43,7 +43,7 @@ <string name="refresh_error" msgid="656062128422446177">"{count,plural, =1{Не удалось проверить параметр}one{Не удалось проверить параметры}few{Не удалось проверить параметры}many{Не удалось проверить параметры}other{Не удалось проверить параметры}}"</string> <string name="work_profile_paused" msgid="7037400224040869079">"Действие рабочего профиля приостановлено."</string> <string name="group_unknown_summary" msgid="6951386960814105641">"Данных пока нет"</string> - <string name="notification_channel_group_name" msgid="7155072032524876859">"Защита и конфиденциальность"</string> + <string name="notification_channel_group_name" msgid="7155072032524876859">"Безопасность и конфиденциальность"</string> <string name="notification_channel_name_information" msgid="2966444432152990166">"Рекомендации"</string> <string name="notification_channel_name_recommendation" msgid="7847408286580217922">"Предупреждения"</string> <string name="notification_channel_name_critical_warning" msgid="5994320322108351769">"Важные предупреждения"</string> diff --git a/SafetyCenter/Resources/shared_res/values-vi/strings.xml b/SafetyCenter/Resources/shared_res/values-vi/strings.xml index 8bbffeb1b..ba9183e54 100644 --- a/SafetyCenter/Resources/shared_res/values-vi/strings.xml +++ b/SafetyCenter/Resources/shared_res/values-vi/strings.xml @@ -20,7 +20,7 @@ <string name="scanning_title" msgid="5424849039854311398">"Quét"</string> <string name="loading_summary" msgid="3740846439782713910">"Đang kiểm tra chế độ cài đặt của thiết bị…"</string> <string name="overall_severity_level_ok_title" msgid="2041250138727564565">"Có vẻ ổn"</string> - <string name="overall_severity_level_ok_summary" msgid="383626536912856690">"Không phát hiện thấy sự cố nào"</string> + <string name="overall_severity_level_ok_summary" msgid="383626536912856690">"Không phát hiện thấy vấn đề nào"</string> <string name="overall_severity_level_tip_summary" msgid="1935765582243024999">"{count,plural, =1{Xem đề xuất}other{Xem các đề xuất}}"</string> <string name="overall_severity_level_action_taken_summary" msgid="8064091657855656545">"{count,plural, =1{Hành động đã thực hiện}other{Hành động đã thực hiện}}"</string> <string name="overall_severity_level_ok_review_title" msgid="1494321117696765360">"Xem lại các chế độ cài đặt"</string> diff --git a/TEST_MAPPING b/TEST_MAPPING index e1bfdde7c..524d02af5 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -53,6 +53,9 @@ "name" : "CtsPermissionMultiUserTestCases" }, { + "name" : "CtsPermissionMultiDeviceTestCases" + }, + { "name": "CtsBackupTestCases", "options": [ { diff --git a/flags/Android.bp b/flags/Android.bp index 4f0241f91..bd711fb16 100644 --- a/flags/Android.bp +++ b/flags/Android.bp @@ -21,45 +21,22 @@ package { aconfig_declarations { name: "permissions-aconfig-flags", package: "com.android.permission.flags", + container: "com.android.permission", srcs: ["flags.aconfig"], } java_aconfig_library { name: "permissions-aconfig-flags-lib", aconfig_declarations: "permissions-aconfig-flags", - sdk_version: "system_current", + sdk_version: "module_current", min_sdk_version: "30", apex_available: [ "com.android.permission", "test_com.android.permission", ], installable: false, + libs: ["framework-configinfrastructure"], visibility: [ "//packages/modules/Permission:__subpackages__", ], } - -java_library { - name: "permissions-flags-lib", - sdk_version: "system_current", - min_sdk_version: "30", - target_sdk_version: "34", - srcs: [ - "java/**/*.java", - ], - static_libs: [ - "permissions-aconfig-flags-lib", - ], - libs: [ - "androidx.annotation_annotation", - "framework-annotations-lib", - ], - apex_available: [ - "com.android.permission", - "test_com.android.permission", - ], - installable: false, - visibility: [ - "//packages/modules/Permission:__subpackages__", - ], -}
\ No newline at end of file diff --git a/flags/flags.aconfig b/flags/flags.aconfig index 37aca2a56..839acb963 100644 --- a/flags/flags.aconfig +++ b/flags/flags.aconfig @@ -1,22 +1,35 @@ package: "com.android.permission.flags" +container: "com.android.permission" flag { - name: "voice_activation_op_enabled" + name: "private_profile_supported" namespace: "permissions" - description: "This flag is used to support hotword activation events in privacy dashboard" - bug: "287264308" + description: "This flag is used to support private profile in safety center" + bug: "286539356" + is_fixed_read_only: true } flag { - name: "device_aware_permission_grant" + name: "private_profile_title_api" + is_exported: true namespace: "permissions" - description: "Enables device aware grant permission flow" - bug: "292252664" + description: "This flag is used to guard the private profile title api in safety center" + bug: "286539356" + is_fixed_read_only: true } flag { - name: "wear_privacy_dashboard_enabled" + name: "wear_privacy_dashboard_enabled_read_only" namespace: "wear_security" description: "This flag is used to support Privacy dashboard for Wear" bug: "309721061" + is_fixed_read_only: true +} + +flag { + name: "archiving_read_only" + namespace: "permissions" + description: "Feature flag to enable the archiving feature." + bug: "278553670" + is_fixed_read_only: true }
\ No newline at end of file diff --git a/framework-s/Android.bp b/framework-s/Android.bp index 850c53f1a..4226b815c 100644 --- a/framework-s/Android.bp +++ b/framework-s/Android.bp @@ -81,6 +81,7 @@ java_sdk_library { "framework-permission-s-shared", "modules-utils-build", "android.permission.flags-aconfig-java", + "permissions-aconfig-flags-lib", ], apex_available: [ "com.android.permission", @@ -94,15 +95,15 @@ java_sdk_library { ], installable: true, jarjar_rules: "jarjar-rules.txt", - lint: { - strict_updatability_linting: true, - baseline_filename: "lint-baseline.xml", - }, min_sdk_version: "31", permitted_packages: [ "android.permission", "android.app.role", + "android.app.ecm", "android.safetycenter", "android.safetylabel", ], + aconfig_declarations: [ + "permissions-aconfig-flags", + ], } diff --git a/framework-s/api/current.txt b/framework-s/api/current.txt index d54af92f5..d943a03a1 100644 --- a/framework-s/api/current.txt +++ b/framework-s/api/current.txt @@ -14,6 +14,7 @@ package android.app.role { field public static final String ROLE_HOME = "android.app.role.HOME"; field public static final String ROLE_NOTES = "android.app.role.NOTES"; field public static final String ROLE_SMS = "android.app.role.SMS"; + field @FlaggedApi("android.permission.flags.wallet_role_enabled") public static final String ROLE_WALLET = "android.app.role.WALLET"; } } diff --git a/framework-s/api/module-lib-current.txt b/framework-s/api/module-lib-current.txt index 80f1cde45..97a8623b3 100644 --- a/framework-s/api/module-lib-current.txt +++ b/framework-s/api/module-lib-current.txt @@ -1,4 +1,12 @@ // Signature format: 2.0 +package android.app.ecm { + + @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") public class EnhancedConfirmationFrameworkInitializer { + method public static void registerServiceWrappers(); + } + +} + package android.app.role { public class RoleFrameworkInitializer { @@ -7,6 +15,7 @@ package android.app.role { public final class RoleManager { method @Nullable public String getBrowserRoleHolder(int); + method @FlaggedApi("android.permission.flags.get_emergency_role_holder_api_enabled") @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getEmergencyRoleHolder(int); method @Nullable public String getSmsRoleHolder(int); method @Nullable @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public boolean setBrowserRoleHolder(@Nullable String, int); } diff --git a/framework-s/api/system-current.txt b/framework-s/api/system-current.txt index b5c379937..e15887576 100644 --- a/framework-s/api/system-current.txt +++ b/framework-s/api/system-current.txt @@ -1,4 +1,17 @@ // Signature format: 2.0 +package android.app.ecm { + + @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") public final class EnhancedConfirmationManager { + method @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) public void clearRestriction(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public android.content.Intent createRestrictedSettingDialogIntent(@NonNull String, @NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) public boolean isClearRestrictionAllowed(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) public boolean isRestricted(@NonNull String, @NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) public void setClearRestrictionAllowed(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + field public static final String ACTION_SHOW_ECM_RESTRICTED_SETTING_DIALOG = "android.app.ecm.action.SHOW_ECM_RESTRICTED_SETTING_DIALOG"; + } + +} + package android.app.role { public interface OnRoleHoldersChangedListener { @@ -558,6 +571,7 @@ package android.safetycenter.config { method public int getProfile(); method @StringRes public int getSearchTermsResId(); method @StringRes public int getSummaryResId(); + method @FlaggedApi("com.android.permission.flags.private_profile_title_api") @StringRes public int getTitleForPrivateProfileResId(); method @StringRes public int getTitleForWorkResId(); method @StringRes public int getTitleResId(); method public int getType(); @@ -593,6 +607,7 @@ package android.safetycenter.config { method @NonNull public android.safetycenter.config.SafetySource.Builder setRefreshOnPageOpenAllowed(boolean); method @NonNull public android.safetycenter.config.SafetySource.Builder setSearchTermsResId(@StringRes int); method @NonNull public android.safetycenter.config.SafetySource.Builder setSummaryResId(@StringRes int); + method @FlaggedApi("com.android.permission.flags.private_profile_title_api") @NonNull public android.safetycenter.config.SafetySource.Builder setTitleForPrivateProfileResId(@StringRes int); method @NonNull public android.safetycenter.config.SafetySource.Builder setTitleForWorkResId(@StringRes int); method @NonNull public android.safetycenter.config.SafetySource.Builder setTitleResId(@StringRes int); } diff --git a/framework-s/jarjar-rules.txt b/framework-s/jarjar-rules.txt index 39f2ad3b7..da8f5a5f1 100644 --- a/framework-s/jarjar-rules.txt +++ b/framework-s/jarjar-rules.txt @@ -1,5 +1,8 @@ rule android.os.HandlerExecutor android.permission.jarjar.@0 -rule android.permission.flags.** android.permission.jarjar.@0 +rule android.permission.flags.*Flags* android.permission.jarjar.@0 +rule android.permission.flags.Flags android.permission.jarjar.@0 rule android.util.IndentingPrintWriter android.permission.jarjar.@0 rule com.android.internal.** android.permission.jarjar.@0 rule com.android.modules.** android.permission.jarjar.@0 +rule com.android.permission.flags.*Flags* android.permission.jarjar.@0 +rule com.android.permission.flags.Flags android.permission.jarjar.@0 diff --git a/framework-s/java/android/app/ecm/EnhancedConfirmationFrameworkInitializer.java b/framework-s/java/android/app/ecm/EnhancedConfirmationFrameworkInitializer.java new file mode 100644 index 000000000..1a42f7ee2 --- /dev/null +++ b/framework-s/java/android/app/ecm/EnhancedConfirmationFrameworkInitializer.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.ecm; + +import android.annotation.FlaggedApi; +import android.annotation.SystemApi; +import android.annotation.TargetApi; +import android.app.SystemServiceRegistry; +import android.content.Context; +import android.os.Build; +import android.permission.flags.Flags; + +/** + * Class holding initialization code for enhanced confirmation code in the permission module. + * + * @hide + */ +@FlaggedApi(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) +@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public class EnhancedConfirmationFrameworkInitializer { + private EnhancedConfirmationFrameworkInitializer() {} + + /** + * Called by {@link SystemServiceRegistry}'s static initializer and registers + * {@link EnhancedConfirmationManager} to {@link Context}, so that + * {@link Context#getSystemService} can return it. + * + * <p>If this is called from other places, it throws a {@link IllegalStateException}. + */ + public static void registerServiceWrappers() { + SystemServiceRegistry.registerContextAwareService(Context.ECM_ENHANCED_CONFIRMATION_SERVICE, + EnhancedConfirmationManager.class, + (context, serviceBinder) -> new EnhancedConfirmationManager(context, + IEnhancedConfirmationManager.Stub.asInterface(serviceBinder))); + } +} diff --git a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java new file mode 100644 index 000000000..74062165e --- /dev/null +++ b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.ecm; + +import static android.annotation.SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION; + +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.annotation.RequiresPermission; +import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.annotation.SystemService; +import android.annotation.TargetApi; +import android.app.AppOpsManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Build; +import android.os.RemoteException; +import android.permission.flags.Flags; +import android.util.ArraySet; + +import androidx.annotation.NonNull; + +import java.lang.annotation.Retention; + +/** + * This class provides the core API for ECM (Enhanced Confirmation Mode). ECM is a feature that + * restricts access to protected **settings** (i.e., sensitive resources) by restricted **apps** + * (apps from from dangerous sources, such as sideloaded packages or packages downloaded from a web + * browser). + * + * <p>Specifically, this class provides the ability to: + * + * <ol> + * <li>Check whether a setting is restricted from an app ({@link #isRestricted}) + * <li>Get an intent that will open the "Restricted setting" dialog ({@link + * #createRestrictedSettingDialogIntent}) (a dialog that informs the user that the operation + * they've attempted to perform is restricted) + * <li>Check whether an app is eligible to have its restriction status cleared ({@link + * #isClearRestrictionAllowed}) + * <li>Clear an app's restriction status (i.e., un-restrict it). ({@link #clearRestriction}) + * </ol> + * + * <p>Methods of this class will generally accept an app (identified by a packageName and a user) + * and a "setting" (a string representing the "sensitive resource") as arguments. ECM's exact + * behavior will generally depend on what restriction state ECM considers each setting and app. For + * example: + * + * <ol> + * <li>A setting may be considered by ECM to be either **protected** or **not protected**. In + * general, this should be considered hardcoded into ECM's implementation: nothing can + * "protect" or "unprotect" a setting. + * <li>An app may be considered as being **not restricted** or **restricted**. A restricted app + * will be restricted from accessing all protected settings. Whether ECM considers any + * particular app restricted is an implementation detail of ECM. However, the user is able to + * clear any restricted app's restriction status (i.e, un-restrict it), after which ECM will + * consider the app **not restricted**. + * </ol> + * + * Why is ECM needed? Consider the following (pre-ECM) scenario: + * + * <ol> + * <li>The user downloads and installs an apk file from a browser. + * <li>The user opens Settings -> Accessibility + * <li>The user tries to register the app as an accessibility service. + * <li>The user is shown a permission prompt "Allow _ to have full control of your device?" + * <li>The user clicks "Allow" + * <li>The downloaded app now has full control of the device. + * </ol> + * + * The purpose of ECM is to add more friction to this scenario. + * + * <p>With ECM, this scenario becomes: + * + * <ol> + * <li>The user downloads and installs an apk file from a browser. + * <li>The user goes into Settings -> Accessibility. + * <li>The user tries to register the app as an accessibility service. + * <li>The user is presented with a "Restricted setting" dialog explaining that the attempted + * action has been restricted. (No "allow" button is shown, but a link is given to a screen + * with intentionally-obscure instructions on how to proceed.) + * <li>The user must now navigate to Settings -> Apps -> [app] + * <li>The user then must click on "..." (top-right corner hamburger menu), then click "Allow + * restricted settings" + * <li>The user goes (again) into Settings -> Accessibility and (again) tries to register the app + * as an accessibility service. + * <li>The user is shown a permission prompt "Allow _ to have full control of your device?" + * <li>The user clicks "Allow" + * <li>The downloaded app now has full control of the device. + * </ol> + * + * And, expanding on the above scenario, the role that this class plays is as follows: + * + * <ol> + * <li>The user downloads and installs an apk file from a browser. + * <li>The user goes into Settings -> Accessibility. + * <p>**This screen then calls {@link #isRestricted}, which checks whether each app listed + * on-screen is restricted from the accessibility service setting. It uses this to visually + * "gray out" restricted apps.** + * <li>The user tries to register the app as an accessibility service. + * <p>**This screen then calls {@link #createRestrictedSettingDialogIntent} and starts the + * intent. This opens the "Restricted setting" dialog.** + * <li>The user is presented with a "Restricted setting" dialog explaining that the attempted + * action is restricted. (No "allow" button is shown, but a link is given to a screen with + * intentionally-obscure instructions on how to proceed.) + * <p>**Upon opening, this dialog marks the app as eligible to have its restriction status + * cleared.** + * <li>The user must now navigate to Settings -> Apps -> [app]. + * <p>**This screen calls {@link #isClearRestrictionAllowed} to check whether the app is + * eligible to have its restriction status cleared. If this returns {@code true}, this screen + * should then show a "Allow restricted setting" button inside the top-right hamburger menu.** + * <li>The user then must click on "..." (top-right corner hamburger menu), then click "Allow + * restricted settings". + * <p>**In response, this screen should now call {@link #clearRestriction}.** + * <li>The user goes (again) into Settings -> Accessibility and (again) tries to register the app + * as an accessibility service. + * <li>The user is shown a permission prompt "Allow _ to have full control of your device?" + * <li>The user clicks "Allow" + * <li>The downloaded app now has full control of the device. + * </ol> + * + * @hide + */ +@SystemApi +@FlaggedApi(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) +@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) +@SystemService(Context.ECM_ENHANCED_CONFIRMATION_SERVICE) +public final class EnhancedConfirmationManager { + /* + * At the API level, we use the following terminology: + * + * - The capability of an app to access a setting may be considered (by ECM) to be *restricted* + * or *not restricted*. + * - A setting may be considered (by ECM) to be *protected* or *not protected*. + * - The state of an app may be considered (by ECM) to be *restricted* or *not restricted* + * + * In this implementation, however, the state of an app is considered either **guarded** or + * **not guarded**; these terms can generally be considered synonymous with **restricted** and + * **not restricted**. (Keeping in mind that, the capability of any app to access any + * non-protected setting will always be considered "not restricted", even if the state of the + * app is considered "restricted".). An app can also be in a third state: **guarded and + * acknowledged**, which corresponds with an app that is restricted and is eligible to have its + * restriction status cleared. + * + * Currently, the ECM state of any given app is stored in the OP_ACCESS_RESTRICTED_SETTINGS + * appop (though this may change in the future): + * + * - MODE_ALLOWED means the app is explicitly **not guarded**. (U- default) + * - MODE_ERRORED means the app is explicitly **guarded**. (Only settable in U-.) + * - MODE_IGNORED means the app is explicitly **guarded and acknowledged**. (An app enters this + * state as soon as the "Restricted setting" dialog has been shown to the user. If an app is + * in this state, Settings is now allowed to provide the user with the option to clear the + * restriction.) + * - MODE_DEFAULT means the app's ECM state should be decided lazily. (V+ default) (That is, + * each time a caller checks whether or not an app is considered guarded by ECM, we'll run an + * heuristic to determine this.) + * + * Some notes on compatibility: + * + * - On U-, MODE_ALLOWED is the default mode of OP_ACCESS_RESTRICTED_SETTINGS. On both U- and + * V+, this is also the mode after the app's restriction has been cleared. + * - In U-, the mode needed to be explicitly set (for example, by a browser that allows a + * dangerous app to be installed) to MODE_ERRORED to indicate that an app is guarded. In V+, + * we no longer allow an app to be placed into MODE_ERRORED, but for compatibility, we still + * recognize MODE_ERRORED to indicate that an app is explicitly guarded. + * - In V+, the default mode is MODE_DEFAULT. Unlike U-, this potentially affects *all* apps, + * not just the ones which have been explicitly marked as **guarded**. + * + * Regarding ECM "setting"s: a setting may be any abstract resource identified by a string. ECM + * may consider any particular setting **protected** or **not protected**. For now, the set of + * protected settings is hardcoded, but this may evolve in the future. + * + * TODO(b/320512579): These methods currently enforce UPDATE_APP_OPS_STATS, + * UPDATE_APP_OPS_STATS, and, for setter methods, MANAGE_APP_OPS_MODES. We should add + * RequiresPermission annotations, but we can't, because some of these permissions are hidden + * API. Either upgrade these to SystemApi or enforce a different permission, then add the + * appropriate RequiresPermission annotation. + */ + + /** + * Shows the "Restricted setting" dialog. Opened when a setting is blocked. + */ + @SdkConstant(BROADCAST_INTENT_ACTION) + public static final String ACTION_SHOW_ECM_RESTRICTED_SETTING_DIALOG = + "android.app.ecm.action.SHOW_ECM_RESTRICTED_SETTING_DIALOG"; + + /** A map of ECM states to their corresponding app op states */ + @Retention(java.lang.annotation.RetentionPolicy.SOURCE) + @IntDef(prefix = {"ECM_STATE_"}, value = {EcmState.ECM_STATE_NOT_GUARDED, + EcmState.ECM_STATE_GUARDED, EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED, + EcmState.ECM_STATE_IMPLICIT}) + private @interface EcmState { + int ECM_STATE_NOT_GUARDED = AppOpsManager.MODE_ALLOWED; + int ECM_STATE_GUARDED = AppOpsManager.MODE_ERRORED; + int ECM_STATE_GUARDED_AND_ACKNOWLEDGED = AppOpsManager.MODE_IGNORED; + int ECM_STATE_IMPLICIT = AppOpsManager.MODE_DEFAULT; + } + + private static final String LOG_TAG = EnhancedConfirmationManager.class.getSimpleName(); + + private static final ArraySet<String> PROTECTED_SETTINGS = new ArraySet<>(); + + static { + PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE); + // TODO(b/310654015): Add other explicitly protected settings + } + + private final @NonNull Context mContext; + private final PackageManager mPackageManager; + + private final @NonNull IEnhancedConfirmationManager mService; + + /** + * @hide + */ + public EnhancedConfirmationManager(@NonNull Context context, + @NonNull IEnhancedConfirmationManager service) { + mContext = context; + mPackageManager = context.getPackageManager(); + mService = service; + } + + /** + * Check whether a setting is restricted from an app. + * + * <p>This is {@code true} when the setting is a protected setting (i.e., a sensitive resource), + * and the app is restricted (i.e., considered dangerous), and the user has not yet cleared the + * app's restriction status (i.e., by clicking "Allow restricted settings" for this app). + * + * @param packageName package name of the application to check for + * @param settingIdentifier identifier of the resource to check to check for + * @return {@code true} if the setting is restricted from the app + * @throws NameNotFoundException if the provided package was not found + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) + public boolean isRestricted(@NonNull String packageName, @NonNull String settingIdentifier) + throws NameNotFoundException { + try { + return mService.isRestricted(packageName, settingIdentifier, + mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Clear an app's restriction status (i.e., un-restrict it). + * + * <p>After this is called, the app will no longer be restricted from accessing any protected + * setting by ECM. This method should be called when the user clicks "Allow restricted settings" + * for the app. + * + * @param packageName package name of the application to remove protection from + * @throws NameNotFoundException if the provided package was not found + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) + public void clearRestriction(@NonNull String packageName) throws NameNotFoundException { + try { + mService.clearRestriction(packageName, mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Check whether the provided app is eligible to have its restriction status cleared (i.e., the + * app is restricted, and the "Restricted setting" dialog has been presented to the user). + * + * <p>The Settings UI should use method this to check whether to present the user with the + * "Allow restricted settings" button. + * + * @param packageName package name of the application to check for + * @return {@code true} if the settings UI should present the user with the ability to clear + * restrictions from the provided app + * @throws NameNotFoundException if the provided package was not found + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) + public boolean isClearRestrictionAllowed(@NonNull String packageName) + throws NameNotFoundException { + try { + return mService.isClearRestrictionAllowed(packageName, + mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Mark the app as eligible to have its restriction status cleared. + * + * <p>This should be called from the "Restricted setting" dialog (which {@link + * #createRestrictedSettingDialogIntent} directs to) upon being presented to the user. + * + * @param packageName package name of the application which should be considered acknowledged + * @throws NameNotFoundException if the provided package was not found + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) + public void setClearRestrictionAllowed(@NonNull String packageName) + throws NameNotFoundException { + try { + mService.setClearRestrictionAllowed(packageName, mContext.getUser().getIdentifier()); + } catch (IllegalArgumentException e) { + throw new NameNotFoundException(packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Gets an intent that will open the "Restricted setting" dialog for the specified package + * and setting. + * + * <p>The "Restricted setting" dialog is a dialog that informs the user that the operation + * they've attempted to perform is restricted, and provides them with a link explaining how to + * proceed. + * + * @param packageName package name of the restricted application + * @param settingIdentifier identifier of the restricted setting + * @throws NameNotFoundException if the provided package was not found + */ + public @NonNull Intent createRestrictedSettingDialogIntent(@NonNull String packageName, + @NonNull String settingIdentifier) throws NameNotFoundException { + Intent intent = new Intent(ACTION_SHOW_ECM_RESTRICTED_SETTING_DIALOG); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(Intent.EXTRA_UID, getPackageUid(packageName)); + intent.putExtra(Intent.EXTRA_SUBJECT, settingIdentifier); + return intent; + } + + private int getPackageUid(String packageName) throws NameNotFoundException { + return mPackageManager.getApplicationInfoAsUser(packageName, /* flags */ 0, + mContext.getUser()).uid; + } +} diff --git a/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl b/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl new file mode 100644 index 000000000..5149daa49 --- /dev/null +++ b/framework-s/java/android/app/ecm/IEnhancedConfirmationManager.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.ecm; + +import android.os.RemoteCallback; + +/** + * @hide + */ +interface IEnhancedConfirmationManager { + + boolean isRestricted(in String packageName, in String settingIdentifier, int userId); + + void clearRestriction(in String packageName, int userId); + + boolean isClearRestrictionAllowed(in String packageName, int userId); + + void setClearRestrictionAllowed(in String packageName, int userId); +} diff --git a/framework-s/java/android/app/role/IRoleManager.aidl b/framework-s/java/android/app/role/IRoleManager.aidl index 0aef871e6..522967630 100644 --- a/framework-s/java/android/app/role/IRoleManager.aidl +++ b/framework-s/java/android/app/role/IRoleManager.aidl @@ -74,6 +74,8 @@ interface IRoleManager { String getSmsRoleHolder(int userId); + String getEmergencyRoleHolder(int userId); + boolean isRoleVisibleAsUser(in String roleName, int userId); boolean isApplicationVisibleForRoleAsUser(in String roleName, in String packageName, diff --git a/framework-s/java/android/app/role/RoleControllerManager.java b/framework-s/java/android/app/role/RoleControllerManager.java index 57da2ccd0..72228c7ca 100644 --- a/framework-s/java/android/app/role/RoleControllerManager.java +++ b/framework-s/java/android/app/role/RoleControllerManager.java @@ -50,10 +50,15 @@ import java.util.function.Consumer; public class RoleControllerManager { /** - * Bundle key for getting legacy fallback disabled roles + * Bundle key for the payload of RoleController APIs */ - public static final String KEY_LEGACY_FALLBACK_DISABLED_ROLES = - "LEGACY_FALLBACK_DISABLED_ROLES"; + public static final String KEY_RESULT = RoleControllerManager.class.getName() + ".key.RESULT"; + + /** + * Bundle key for the error of RoleController APIs + */ + public static final String KEY_EXCEPTION = RoleControllerManager.class.getName() + + ".key.EXCEPTION"; private static final String LOG_TAG = RoleControllerManager.class.getSimpleName(); @@ -145,9 +150,9 @@ public class RoleControllerManager { */ public void grantDefaultRoles(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); - service.grantDefaultRoles(new RemoteCallback(future::complete)); + AndroidFuture<Boolean> operation = mRemoteService.postAsync(service -> { + AndroidFuture<Boolean> future = new AndroidFuture<>(); + service.grantDefaultRoles(createBooleanRemoteCallback(future)); return future; }); propagateCallback(operation, "grantDefaultRoles", executor, callback); @@ -160,10 +165,10 @@ public class RoleControllerManager { */ public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); + AndroidFuture<Boolean> operation = mRemoteService.postAsync(service -> { + AndroidFuture<Boolean> future = new AndroidFuture<>(); service.onAddRoleHolder(roleName, packageName, flags, - new RemoteCallback(future::complete)); + createBooleanRemoteCallback(future)); return future; }); propagateCallback(operation, "onAddRoleHolder", callback); @@ -176,10 +181,10 @@ public class RoleControllerManager { */ public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); + AndroidFuture<Boolean> operation = mRemoteService.postAsync(service -> { + AndroidFuture<Boolean> future = new AndroidFuture<>(); service.onRemoveRoleHolder(roleName, packageName, flags, - new RemoteCallback(future::complete)); + createBooleanRemoteCallback(future)); return future; }); propagateCallback(operation, "onRemoveRoleHolder", callback); @@ -192,9 +197,9 @@ public class RoleControllerManager { */ public void onClearRoleHolders(@NonNull String roleName, @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); - service.onClearRoleHolders(roleName, flags, new RemoteCallback(future::complete)); + AndroidFuture<Boolean> operation = mRemoteService.postAsync(service -> { + AndroidFuture<Boolean> future = new AndroidFuture<>(); + service.onClearRoleHolders(roleName, flags, createBooleanRemoteCallback(future)); return future; }); propagateCallback(operation, "onClearRoleHolders", callback); @@ -208,10 +213,10 @@ public class RoleControllerManager { @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) public void isApplicationVisibleForRole(@NonNull String roleName, @NonNull String packageName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); + AndroidFuture<Boolean> operation = mRemoteService.postAsync(service -> { + AndroidFuture<Boolean> future = new AndroidFuture<>(); service.isApplicationVisibleForRole(roleName, packageName, - new RemoteCallback(future::complete)); + createBooleanRemoteCallback(future)); return future; }); propagateCallback(operation, "isApplicationVisibleForRole", executor, callback); @@ -225,9 +230,9 @@ public class RoleControllerManager { @RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS) public void isRoleVisible(@NonNull String roleName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback) { - AndroidFuture<Bundle> operation = mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); - service.isRoleVisible(roleName, new RemoteCallback(future::complete)); + AndroidFuture<Boolean> operation = mRemoteService.postAsync(service -> { + AndroidFuture<Boolean> future = new AndroidFuture<>(); + service.isRoleVisible(roleName, createBooleanRemoteCallback(future)); return future; }); propagateCallback(operation, "isRoleVisible", executor, callback); @@ -241,8 +246,15 @@ public class RoleControllerManager { public void getLegacyFallbackDisabledRoles(@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<List<String>> callback) { mRemoteService.postAsync(service -> { - AndroidFuture<Bundle> future = new AndroidFuture<>(); - service.getLegacyFallbackDisabledRoles(new RemoteCallback(future::complete)); + AndroidFuture<List<String>> future = new AndroidFuture<>(); + service.getLegacyFallbackDisabledRoles(new RemoteCallback(result -> { + Exception exception = (Exception) result.getSerializable(KEY_EXCEPTION); + if (exception != null) { + future.completeExceptionally(exception); + } else { + future.complete(result.getStringArrayList(KEY_RESULT)); + } + })); return future; }).orTimeout(REQUEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) .whenComplete((res, err) -> executor.execute(() -> { @@ -253,8 +265,7 @@ public class RoleControllerManager { err); callback.accept(null); } else { - callback.accept(res.getStringArrayList( - KEY_LEGACY_FALLBACK_DISABLED_ROLES)); + callback.accept(res); } } finally { Binder.restoreCallingIdentity(token); @@ -262,7 +273,19 @@ public class RoleControllerManager { })); } - private void propagateCallback(AndroidFuture<Bundle> operation, String opName, + @NonNull + private RemoteCallback createBooleanRemoteCallback(@NonNull AndroidFuture<Boolean> future) { + return new RemoteCallback(result -> { + Exception exception = (Exception) result.getSerializable(KEY_EXCEPTION); + if (exception != null) { + future.completeExceptionally(exception); + } else { + future.complete(result.getBoolean(KEY_RESULT)); + } + }); + } + + private void propagateCallback(AndroidFuture<Boolean> operation, String opName, @CallbackExecutor @NonNull Executor executor, Consumer<Boolean> destination) { operation.orTimeout(REQUEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) @@ -273,7 +296,7 @@ public class RoleControllerManager { Log.e(LOG_TAG, "Error calling " + opName + "()", err); destination.accept(false); } else { - destination.accept(res != null); + destination.accept(res); } } finally { Binder.restoreCallingIdentity(token); @@ -281,7 +304,7 @@ public class RoleControllerManager { })); } - private void propagateCallback(AndroidFuture<Bundle> operation, String opName, + private void propagateCallback(AndroidFuture<Boolean> operation, String opName, RemoteCallback destination) { operation.orTimeout(REQUEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) .whenComplete((res, err) -> { @@ -291,7 +314,7 @@ public class RoleControllerManager { Log.e(LOG_TAG, "Error calling " + opName + "()", err); destination.sendResult(null); } else { - destination.sendResult(res); + destination.sendResult(res ? Bundle.EMPTY : null); } } finally { Binder.restoreCallingIdentity(token); diff --git a/framework-s/java/android/app/role/RoleControllerService.java b/framework-s/java/android/app/role/RoleControllerService.java index 60a13f7ba..2155ee4eb 100644 --- a/framework-s/java/android/app/role/RoleControllerService.java +++ b/framework-s/java/android/app/role/RoleControllerService.java @@ -33,6 +33,7 @@ import android.os.Process; import android.os.RemoteCallback; import android.os.UserHandle; import android.permission.flags.Flags; +import android.util.Log; import com.android.internal.util.Preconditions; @@ -56,6 +57,7 @@ import java.util.concurrent.Executor; @Deprecated @SystemApi public abstract class RoleControllerService extends Service { + private static final String LOG_TAG = RoleControllerService.class.getSimpleName(); /** * The {@link Intent} that must be declared as handled by the service. @@ -89,7 +91,6 @@ public abstract class RoleControllerService extends Service { @Override public void grantDefaultRoles(RemoteCallback callback) { enforceCallerSystemUid("grantDefaultRoles"); - Objects.requireNonNull(callback, "callback cannot be null"); mWorkerHandler.post(() -> RoleControllerService.this.grantDefaultRoles(callback)); @@ -99,10 +100,6 @@ public abstract class RoleControllerService extends Service { public void onAddRoleHolder(String roleName, String packageName, int flags, RemoteCallback callback) { enforceCallerSystemUid("onAddRoleHolder"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); Objects.requireNonNull(callback, "callback cannot be null"); mWorkerHandler.post(() -> RoleControllerService.this.onAddRoleHolder(roleName, @@ -113,10 +110,6 @@ public abstract class RoleControllerService extends Service { public void onRemoveRoleHolder(String roleName, String packageName, int flags, RemoteCallback callback) { enforceCallerSystemUid("onRemoveRoleHolder"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); Objects.requireNonNull(callback, "callback cannot be null"); mWorkerHandler.post(() -> RoleControllerService.this.onRemoveRoleHolder(roleName, @@ -126,8 +119,6 @@ public abstract class RoleControllerService extends Service { @Override public void onClearRoleHolders(String roleName, int flags, RemoteCallback callback) { enforceCallerSystemUid("onClearRoleHolders"); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); Objects.requireNonNull(callback, "callback cannot be null"); mWorkerHandler.post(() -> RoleControllerService.this.onClearRoleHolders(roleName, @@ -145,39 +136,54 @@ public abstract class RoleControllerService extends Service { public void isApplicationQualifiedForRole(String roleName, String packageName, RemoteCallback callback) { enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); Objects.requireNonNull(callback, "callback cannot be null"); - boolean qualified = onIsApplicationQualifiedForRole(roleName, packageName); - callback.sendResult(qualified ? Bundle.EMPTY : null); + Bundle result = new Bundle(); + try { + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkStringNotEmpty(packageName, + "packageName cannot be null or empty"); + boolean qualified = onIsApplicationQualifiedForRole(roleName, packageName); + result.putBoolean(RoleControllerManager.KEY_RESULT, qualified); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } + callback.sendResult(result); } @Override public void isApplicationVisibleForRole(String roleName, String packageName, RemoteCallback callback) { enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); - Preconditions.checkStringNotEmpty(packageName, - "packageName cannot be null or empty"); Objects.requireNonNull(callback, "callback cannot be null"); - boolean visible = onIsApplicationVisibleForRole(roleName, packageName); - callback.sendResult(visible ? Bundle.EMPTY : null); + Bundle result = new Bundle(); + try { + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkStringNotEmpty(packageName, + "packageName cannot be null or empty"); + boolean visible = onIsApplicationVisibleForRole(roleName, packageName); + result.putBoolean(RoleControllerManager.KEY_RESULT, visible); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } + callback.sendResult(result); } @Override public void isRoleVisible(String roleName, RemoteCallback callback) { enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null); - - Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); Objects.requireNonNull(callback, "callback cannot be null"); - boolean visible = onIsRoleVisible(roleName); - callback.sendResult(visible ? Bundle.EMPTY : null); + Bundle result = new Bundle(); + try { + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + boolean visible = onIsRoleVisible(roleName); + result.putBoolean(RoleControllerManager.KEY_RESULT, visible); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } + callback.sendResult(result); } @Override @@ -186,36 +192,71 @@ public abstract class RoleControllerService extends Service { Objects.requireNonNull(callback, "callback cannot be null"); - List<String> legacyFallbackDisabledRoles = onGetLegacyFallbackDisabledRoles(); Bundle result = new Bundle(); - result.putStringArrayList(RoleControllerManager.KEY_LEGACY_FALLBACK_DISABLED_ROLES, - new ArrayList<>(legacyFallbackDisabledRoles)); + try { + List<String> legacyFallbackDisabledRoles = onGetLegacyFallbackDisabledRoles(); + result.putStringArrayList(RoleControllerManager.KEY_RESULT, + new ArrayList<>(legacyFallbackDisabledRoles)); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } callback.sendResult(result); } }; } - private void grantDefaultRoles(@NonNull RemoteCallback callback) { - boolean successful = onGrantDefaultRoles(); - callback.sendResult(successful ? Bundle.EMPTY : null); + private void grantDefaultRoles(RemoteCallback callback) { + Bundle result = new Bundle(); + try { + boolean successful = onGrantDefaultRoles(); + result.putBoolean(RoleControllerManager.KEY_RESULT, successful); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } + callback.sendResult(result); } private void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - boolean successful = onAddRoleHolder(roleName, packageName, flags); - callback.sendResult(successful ? Bundle.EMPTY : null); + @RoleManager.ManageHoldersFlags int flags, RemoteCallback callback) { + Bundle result = new Bundle(); + try { + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkStringNotEmpty(packageName, + "packageName cannot be null or empty"); + boolean successful = onAddRoleHolder(roleName, packageName, flags); + result.putBoolean(RoleControllerManager.KEY_RESULT, successful); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } + callback.sendResult(result); } private void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - boolean successful = onRemoveRoleHolder(roleName, packageName, flags); - callback.sendResult(successful ? Bundle.EMPTY : null); + @RoleManager.ManageHoldersFlags int flags, RemoteCallback callback) { + Bundle result = new Bundle(); + try { + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + Preconditions.checkStringNotEmpty(packageName, + "packageName cannot be null or empty"); + boolean successful = onRemoveRoleHolder(roleName, packageName, flags); + result.putBoolean(RoleControllerManager.KEY_RESULT, successful); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } + callback.sendResult(result); } private void onClearRoleHolders(@NonNull String roleName, - @RoleManager.ManageHoldersFlags int flags, @NonNull RemoteCallback callback) { - boolean successful = onClearRoleHolders(roleName, flags); - callback.sendResult(successful ? Bundle.EMPTY : null); + @RoleManager.ManageHoldersFlags int flags, RemoteCallback callback) { + Bundle result = new Bundle(); + try { + Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty"); + boolean successful = onClearRoleHolders(roleName, flags); + result.putBoolean(RoleControllerManager.KEY_RESULT, successful); + } catch (Exception e) { + result.putSerializable(RoleControllerManager.KEY_EXCEPTION, e); + } + callback.sendResult(result); } /** @@ -327,6 +368,8 @@ public abstract class RoleControllerService extends Service { @FlaggedApi(Flags.FLAG_SYSTEM_SERVER_ROLE_CONTROLLER_ENABLED) @NonNull public List<String> onGetLegacyFallbackDisabledRoles() { + Log.wtf(LOG_TAG, "onGetLegacyFallbackDisabledRoles is unsupported by this version of" + + " PermissionController"); throw new UnsupportedOperationException(); } } diff --git a/framework-s/java/android/app/role/RoleManager.java b/framework-s/java/android/app/role/RoleManager.java index 3cf1e94ba..4b8c9b388 100644 --- a/framework-s/java/android/app/role/RoleManager.java +++ b/framework-s/java/android/app/role/RoleManager.java @@ -146,6 +146,15 @@ public final class RoleManager { public static final String ROLE_NOTES = "android.app.role.NOTES"; /** + * The name of the Wallet role. + * + * @see android.nfc.cardemulation.CardEmulation + */ + @FlaggedApi(Flags.FLAG_WALLET_ROLE_ENABLED) + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + public static final String ROLE_WALLET = "android.app.role.WALLET"; + + /** * The name of the system wellbeing role. * * @hide @@ -966,6 +975,28 @@ public final class RoleManager { } /** + * Allows getting the role holder for {@link #ROLE_EMERGENCY} without requiring + * {@link Manifest.permission#OBSERVE_ROLE_HOLDERS}. + * + * @param userId the user ID to get the default emergency package for + * @return the package name of the default emergency app, or {@code null} if none + * + * @hide + */ + @FlaggedApi(Flags.FLAG_GET_EMERGENCY_ROLE_HOLDER_API_ENABLED) + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @Nullable + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public String getEmergencyRoleHolder(@UserIdInt int userId) { + try { + return mService.getEmergencyRoleHolder(userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Check whether a role should be visible to user. * * @param roleName name of the role to check for diff --git a/framework-s/java/android/safetycenter/config/SafetySource.java b/framework-s/java/android/safetycenter/config/SafetySource.java index 8aa897850..ff0c66e24 100644 --- a/framework-s/java/android/safetycenter/config/SafetySource.java +++ b/framework-s/java/android/safetycenter/config/SafetySource.java @@ -18,9 +18,11 @@ package android.safetycenter.config; import static android.os.Build.VERSION_CODES.TIRAMISU; import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; +import static android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM; import static java.util.Objects.requireNonNull; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -34,6 +36,7 @@ import android.util.ArraySet; import androidx.annotation.RequiresApi; import com.android.modules.utils.build.SdkLevel; +import com.android.permission.flags.Flags; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -182,6 +185,9 @@ public final class SafetySource implements Parcelable { builder.addPackageCertificateHash(certs.get(i)); } } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + builder.setTitleForPrivateProfileResId(in.readInt()); + } return builder.build(); } @@ -207,6 +213,7 @@ public final class SafetySource implements Parcelable { private final boolean mNotificationsAllowed; @Nullable final String mDeduplicationGroup; @NonNull private final Set<String> mPackageCertificateHashes; + @StringRes private final int mTitleForPrivateProfileResId; private SafetySource( @SafetySourceType int type, @@ -224,7 +231,8 @@ public final class SafetySource implements Parcelable { boolean refreshOnPageOpenAllowed, boolean notificationsAllowed, @Nullable String deduplicationGroup, - @NonNull Set<String> packageCertificateHashes) { + @NonNull Set<String> packageCertificateHashes, + @StringRes int titleForPrivateProfileResId) { mType = type; mId = id; mPackageName = packageName; @@ -241,6 +249,7 @@ public final class SafetySource implements Parcelable { mNotificationsAllowed = notificationsAllowed; mDeduplicationGroup = deduplicationGroup; mPackageCertificateHashes = Set.copyOf(packageCertificateHashes); + mTitleForPrivateProfileResId = titleForPrivateProfileResId; } /** Returns the type of this safety source. */ @@ -347,6 +356,37 @@ public final class SafetySource implements Parcelable { } /** + * Returns the resource id of the title for private profile of this safety source. + * + * <p>The id refers to a string resource that is either accessible from any resource context or + * that is accessible from the same resource context that was used to load the Safety Center + * configuration. The id is {@link Resources#ID_NULL} when a title for private profile is not + * provided. + * + * @throws UnsupportedOperationException if the source is of type {@link + * SafetySource#SAFETY_SOURCE_TYPE_ISSUE_ONLY} or if the profile property of the source is + * set to {@link SafetySource#PROFILE_PRIMARY} + */ + @FlaggedApi(Flags.FLAG_PRIVATE_PROFILE_TITLE_API) + @RequiresApi(VANILLA_ICE_CREAM) + @StringRes + public int getTitleForPrivateProfileResId() { + if (!SdkLevel.isAtLeastV()) { + throw new UnsupportedOperationException( + "getTitleForPrivateProfileResId unsupported for SDKs lower than V"); + } + if (mType == SAFETY_SOURCE_TYPE_ISSUE_ONLY) { + throw new UnsupportedOperationException( + "getTitleForPrivateProfileResId unsupported for issue-only safety source"); + } + if (mProfile == PROFILE_PRIMARY) { + throw new UnsupportedOperationException( + "getTitleForPrivateProfileResId unsupported for primary profile safety source"); + } + return mTitleForPrivateProfileResId; + } + + /** * Returns the resource id of the summary of this safety source. * * <p>The id refers to a string resource that is either accessible from any resource context or @@ -554,7 +594,8 @@ public final class SafetySource implements Parcelable { && mRefreshOnPageOpenAllowed == that.mRefreshOnPageOpenAllowed && mNotificationsAllowed == that.mNotificationsAllowed && Objects.equals(mDeduplicationGroup, that.mDeduplicationGroup) - && Objects.equals(mPackageCertificateHashes, that.mPackageCertificateHashes); + && Objects.equals(mPackageCertificateHashes, that.mPackageCertificateHashes) + && mTitleForPrivateProfileResId == that.mTitleForPrivateProfileResId; } @Override @@ -575,7 +616,8 @@ public final class SafetySource implements Parcelable { mRefreshOnPageOpenAllowed, mNotificationsAllowed, mDeduplicationGroup, - mPackageCertificateHashes); + mPackageCertificateHashes, + mTitleForPrivateProfileResId); } @Override @@ -613,6 +655,8 @@ public final class SafetySource implements Parcelable { + mDeduplicationGroup + ", mPackageCertificateHashes=" + mPackageCertificateHashes + + ", mTitleForPrivateProfileResId=" + + mTitleForPrivateProfileResId + '}'; } @@ -641,6 +685,9 @@ public final class SafetySource implements Parcelable { dest.writeString(mDeduplicationGroup); dest.writeStringList(List.copyOf(mPackageCertificateHashes)); } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + dest.writeInt(mTitleForPrivateProfileResId); + } } /** Builder class for {@link SafetySource}. */ @@ -662,6 +709,7 @@ public final class SafetySource implements Parcelable { @Nullable private Boolean mNotificationsAllowed; @Nullable private String mDeduplicationGroup; @NonNull private final ArraySet<String> mPackageCertificateHashes = new ArraySet<>(); + @Nullable @StringRes private Integer mTitleForPrivateProfileResId; /** Creates a {@link Builder} for a {@link SafetySource}. */ public Builder(@SafetySourceType int type) { @@ -692,6 +740,7 @@ public final class SafetySource implements Parcelable { mNotificationsAllowed = safetySource.mNotificationsAllowed; mDeduplicationGroup = safetySource.mDeduplicationGroup; mPackageCertificateHashes.addAll(safetySource.mPackageCertificateHashes); + mTitleForPrivateProfileResId = safetySource.mTitleForPrivateProfileResId; } /** @@ -759,6 +808,32 @@ public final class SafetySource implements Parcelable { } /** + * Sets the resource id of the title for private profile of this safety source. + * + * <p>The id must refer to a string resource that is either accessible from any resource + * context or that is accessible from the same resource context that was used to load the + * Safety Center configuration. The id defaults to {@link Resources#ID_NULL} when a title + * for private profile is not provided. + * + * <p>The title for private profile is required if the profile property of the source is set + * to {@link SafetySource#PROFILE_ALL} and either the source is of type static or the source + * is a source of type dynamic that is not hidden and that does not provide search terms. + * The title for private profile is prohibited for sources of type issue-only and if the + * profile property of the source is not set to {@link SafetySource#PROFILE_ALL}. + */ + @FlaggedApi(Flags.FLAG_PRIVATE_PROFILE_TITLE_API) + @RequiresApi(VANILLA_ICE_CREAM) + @NonNull + public Builder setTitleForPrivateProfileResId(@StringRes int titleForPrivateProfileResId) { + if (!SdkLevel.isAtLeastV()) { + throw new UnsupportedOperationException( + "setTitleForPrivateProfileResId unsupported for SDKs lower than V"); + } + mTitleForPrivateProfileResId = titleForPrivateProfileResId; + return this; + } + + /** * Sets the resource id of the summary of this safety source. * * <p>The id must refer to a string resource that is either accessible from any resource @@ -984,7 +1059,7 @@ public final class SafetySource implements Parcelable { PROFILE_NONE, PROFILE_PRIMARY, PROFILE_ALL); - boolean hasWork = profile == PROFILE_ALL; + boolean hasAllProfiles = profile == PROFILE_ALL; int searchTermsResId = BuilderUtils.validateResId( @@ -1000,8 +1075,8 @@ public final class SafetySource implements Parcelable { BuilderUtils.validateResId( mTitleForWorkResId, "titleForWork", - hasWork && titleRequired, - !hasWork || isIssueOnly); + hasAllProfiles && titleRequired, + !hasAllProfiles || isIssueOnly); int summaryResId = BuilderUtils.validateResId( @@ -1052,6 +1127,16 @@ public final class SafetySource implements Parcelable { packageCertificateHashes, "packageCertificateHashes", false, isStatic); } + int titleForPrivateProfileResId = Resources.ID_NULL; + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + titleForPrivateProfileResId = + BuilderUtils.validateResId( + mTitleForPrivateProfileResId, + "titleForPrivateProfile", + hasAllProfiles && titleRequired, + !hasAllProfiles || isIssueOnly); + } + return new SafetySource( type, id, @@ -1068,7 +1153,8 @@ public final class SafetySource implements Parcelable { refreshOnPageOpenAllowed, notificationsAllowed, deduplicationGroup, - packageCertificateHashes); + packageCertificateHashes, + titleForPrivateProfileResId); } } } diff --git a/framework-s/java/android/safetycenter/config/safety_center_config-v35.xsd b/framework-s/java/android/safetycenter/config/safety_center_config-v35.xsd new file mode 100644 index 000000000..20b1e7655 --- /dev/null +++ b/framework-s/java/android/safetycenter/config/safety_center_config-v35.xsd @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<!-- This file contains comments that define constraints that cannot be covered by the XSD language --> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" + version="1.0"> + + <xsd:element name="safety-center-config" type="safety-center-config"/> + + <xsd:complexType name="safety-center-config"> + <xsd:sequence> + <xsd:element name="safety-sources-config" type="safety-sources-config"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="safety-sources-config"> + <xsd:sequence> + <xsd:element + name="safety-sources-group" type="safety-sources-group" + minOccurs="1" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="safety-sources-group"> + <xsd:choice minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="dynamic-safety-source" type="dynamic-safety-source"/> + <xsd:element name="static-safety-source" type="static-safety-source"/> + <xsd:element name="issue-only-safety-source" type="issue-only-safety-source"/> + </xsd:choice> + <!-- id must be unique among safety sources groups --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <!-- title is required unless the group contains issue only and/or internal sources --> + <xsd:attribute name="title" type="runtimeStringResourceName"/> + <xsd:attribute name="summary" type="runtimeStringResourceName"/> + <xsd:attribute name="statelessIconType" type="statelessIconTypeOrStringResourceName" + default="none"/> + <!-- type is inferred from other attributes and the group content if omitted --> + <xsd:attribute name="type" type="groupTypeOrStringResourceName"/> + </xsd:complexType> + + <xsd:complexType name="dynamic-safety-source"> + <!-- id must be unique among safety sources --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <xsd:attribute name="packageName" type="stringOrStringResourceName" use="required"/> + <!-- optional comma-separated set of certificate hashes, if provided will be used for validation. --> + <xsd:attribute name="packageCertificateHashes" type="stringOrStringResourceName"/> + <!-- title is required if initialDisplayState is not set to hidden or if searchTerms are provided --> + <xsd:attribute name="title" type="runtimeStringResourceName"/> + <!-- titleForWork is required if profile is set to all_profiles, and initialDisplayState is not set to hidden or if searchTerms are provided --> + <!-- titleForWork is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForWork" type="runtimeStringResourceName"/> + <!-- titleForPrivateProfile is required if profile is set to all_profiles, and initialDisplayState is not set to hidden or if searchTerms are provided --> + <!-- titleForPrivateProfile is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForPrivateProfile" type="runtimeStringResourceName"/> + <!-- summary is required if initialDisplayState is not set to hidden --> + <xsd:attribute name="summary" type="runtimeStringResourceName"/> + <!-- intentAction is required if initialDisplayState is set to enabled --> + <xsd:attribute name="intentAction" type="stringOrStringResourceName"/> + <xsd:attribute name="profile" type="profile" use="required"/> + <xsd:attribute name="initialDisplayState" type="initialDisplayStateOrStringResourceName" + default="enabled"/> + <xsd:attribute name="maxSeverityLevel" type="intOrStringResourceName" default="2147483647"/> + <xsd:attribute name="searchTerms" type="runtimeStringResourceName"/> + <xsd:attribute name="loggingAllowed" type="booleanOrStringResourceName" default="true"/> + <xsd:attribute name="refreshOnPageOpenAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="notificationsAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="deduplicationGroup" type="stringOrStringResourceName"/> + </xsd:complexType> + + <xsd:complexType name="issue-only-safety-source"> + <!-- id must be unique among safety sources --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <xsd:attribute name="packageName" type="stringOrStringResourceName" use="required"/> + <!-- optional comma-separated set of certificate hashes, if provided will be used for validation. --> + <xsd:attribute name="packageCertificateHashes" type="stringOrStringResourceName"/> + <xsd:attribute name="profile" type="profileOrStringResourceName" use="required"/> + <xsd:attribute name="maxSeverityLevel" type="intOrStringResourceName" default="2147483647"/> + <xsd:attribute name="loggingAllowed" type="booleanOrStringResourceName" default="true"/> + <xsd:attribute name="refreshOnPageOpenAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="notificationsAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="deduplicationGroup" type="stringOrStringResourceName"/> + </xsd:complexType> + + <xsd:complexType name="static-safety-source"> + <!-- id must be unique among safety sources --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <xsd:attribute name="packageName" type="stringOrStringResourceName"/> + <xsd:attribute name="title" type="runtimeStringResourceName" use="required"/> + <!-- titleForWork is required if profile is set to all_profiles --> + <!-- titleForWork is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForWork" type="runtimeStringResourceName"/> + <!-- titleForPrivateProfile is required if profile is set to all_profiles --> + <!-- titleForPrivateProfile is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForPrivateProfile" type="runtimeStringResourceName"/> + <xsd:attribute name="summary" type="runtimeStringResourceName"/> + <xsd:attribute name="intentAction" type="stringOrStringResourceName" use="required"/> + <xsd:attribute name="profile" type="profileOrStringResourceName" use="required"/> + <xsd:attribute name="searchTerms" type="runtimeStringResourceName"/> + </xsd:complexType> + + <xsd:simpleType name="intOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type xsd:int. --> + <xsd:union memberTypes="stringResourceName xsd:int"/> + </xsd:simpleType> + + <xsd:simpleType name="booleanOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type xsd:boolean. --> + <xsd:union memberTypes="stringResourceName xsd:boolean"/> + </xsd:simpleType> + + <xsd:simpleType name="stringOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type xsd:string. --> + <xsd:union memberTypes="stringResourceName xsd:string"/> + </xsd:simpleType> + + <xsd:simpleType name="idOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type xsd:string. --> + <xsd:union memberTypes="stringResourceName id"/> + </xsd:simpleType> + + <xsd:simpleType name="id"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="[0-9a-zA-Z_-]+"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="statelessIconTypeOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type statelessIconType. --> + <xsd:union memberTypes="stringResourceName statelessIconType"/> + </xsd:simpleType> + + <xsd:simpleType name="statelessIconType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="none"/> + <xsd:enumeration value="privacy"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="profileOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type profile. --> + <xsd:union memberTypes="stringResourceName profile"/> + </xsd:simpleType> + + <xsd:simpleType name="profile"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="primary_profile_only"/> + <xsd:enumeration value="all_profiles"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="initialDisplayStateOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type initialDisplayState. --> + <xsd:union memberTypes="stringResourceName initialDisplayState"/> + </xsd:simpleType> + + <xsd:simpleType name="initialDisplayState"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="enabled"/> + <xsd:enumeration value="disabled"/> + <xsd:enumeration value="hidden"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="groupTypeOrStringResourceName"> + <!-- String resource names will be resolved only once at parse time. --> + <!-- Locale changes and device config changes will be ignored. --> + <!-- The value of the string resource must be of type groupType. --> + <xsd:union memberTypes="stringResourceName groupType"/> + </xsd:simpleType> + + <xsd:simpleType name="groupType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="stateless"/> + <xsd:enumeration value="stateful"/> + <xsd:enumeration value="hidden"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="runtimeStringResourceName"> + <!-- String resource names will be resolved at runtime whenever the string value is used. --> + <xsd:union memberTypes="stringResourceName"/> + </xsd:simpleType> + + <!-- String resource names will be ignored for any attribute not directly or indirectly marked as stringResourceName. --> + <!-- A stringResourceName is a fully qualified resource name of the form "@package:string/entry". Package is required. --> + <xsd:simpleType name="stringResourceName"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="@([a-z]+\.)*[a-z]+:string/.+"/> + </xsd:restriction> + </xsd:simpleType> + +</xsd:schema> diff --git a/framework-s/lint-baseline.xml b/framework-s/lint-baseline.xml index b91b959e4..eb4ed1796 100644 --- a/framework-s/lint-baseline.xml +++ b/framework-s/lint-baseline.xml @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> -<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev"> +<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01"> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.content.Context#getUser`" - errorLine1=" .append(String.valueOf(mContext.getUser().getIdentifier())).println();" - errorLine2=" ~~~~~~~"> + message="Call requires API level 33 (current min is 30): `android.util.Slog#e`" + errorLine1=' Slog.e(LOG_TAG, "Failed to unbind: " + e);' + errorLine2=" ~"> <location file="frameworks/base/core/java/com/android/internal/infra/ServiceConnector.java" - line="707" - column="53"/> + line="576" + column="26"/> </issue> <issue @@ -25,13 +25,13 @@ <issue id="NewApi" - message="Call requires API level 33 (current min is 30): `android.util.Slog#e`" - errorLine1=' Slog.e(LOG_TAG, "Failed to unbind: " + e);' - errorLine2=" ~"> + message="Call requires API level 31 (current min is 30): `android.content.Context#getUser`" + errorLine1=" .append(String.valueOf(mContext.getUser().getIdentifier())).println();" + errorLine2=" ~~~~~~~"> <location file="frameworks/base/core/java/com/android/internal/infra/ServiceConnector.java" - line="576" - column="26"/> + line="707" + column="53"/> </issue> </issues>
\ No newline at end of file diff --git a/framework/java/android/permission/PermissionState.java b/framework/java/android/permission/PermissionStateUnused.java index e810db8ec..21b21cc27 100644 --- a/framework/java/android/permission/PermissionState.java +++ b/framework/java/android/permission/PermissionStateUnused.java @@ -19,4 +19,4 @@ package android.permission; /** * @hide */ -public class PermissionState {} +public class PermissionStateUnused {} diff --git a/service/Android.bp b/service/Android.bp index 64f0dd5e2..712aed793 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -45,9 +45,6 @@ java_library { "com.android.permission", "test_com.android.permission", ], - lint: { - baseline_filename: "lint-baseline.xml", - }, } java_library { @@ -66,9 +63,6 @@ java_library { installable: false, min_sdk_version: "30", sdk_version: "system_server_current", - lint: { - baseline_filename: "lint-baseline.xml", - }, } java_sdk_library { @@ -115,8 +109,10 @@ java_sdk_library { "safety-center-resources-lib", "service-permission-shared", "service-permission-statsd", + "permissioncontroller-statsd", "service-permission-proto-stream", "android.permission.flags-aconfig-java", + "permissions-aconfig-flags-lib", ], errorprone: { javacflags: ["-Xep:GuardedBy:ERROR"], @@ -131,7 +127,6 @@ java_sdk_library { "-Xno-receiver-assertions", ], lint: { - strict_updatability_linting: true, baseline_filename: "lint-baseline.xml", }, min_sdk_version: "30", @@ -143,6 +138,7 @@ java_sdk_library { installable: true, permitted_packages: [ "com.android.access", + "com.android.ecm", "com.android.permission", "com.android.role", "com.android.safetycenter", @@ -151,6 +147,9 @@ java_sdk_library { proguard_compatibility: false, // TODO(b/215530220): remove when this is default behavior proguard_flags_files: ["proguard.flags"], }, + aconfig_declarations: [ + "permissions-aconfig-flags", + ], } genrule { @@ -176,7 +175,4 @@ java_library { ], min_sdk_version: "30", sdk_version: "system_server_current", - lint: { - baseline_filename: "lint-baseline.xml", - }, } diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt index a3fd75930..5bba54616 100644 --- a/service/jarjar-rules.txt +++ b/service/jarjar-rules.txt @@ -1,8 +1,11 @@ rule android.os.HandlerExecutor com.android.permission.jarjar.@0 -rule android.permission.flags.** com.android.permission.jarjar.@0 +rule android.permission.flags.*Flags* com.android.permission.jarjar.@0 +rule android.permission.flags.Flags com.android.permission.jarjar.@0 rule android.util.IndentingPrintWriter com.android.permission.jarjar.@0 rule com.android.internal.** com.android.permission.jarjar.@0 rule com.android.modules.** com.android.permission.jarjar.@0 +rule com.android.permission.flags.*Flags* com.android.permission.jarjar.@0 +rule com.android.permission.flags.Flags com.android.permission.jarjar.@0 rule com.android.role.*Proto com.android.permission.jarjar.@0 # TODO(b/236200992): Revisit addition of rule com.android.safetycenter.annotations, # com.android.safetycenter.internaldata, com.android.safetycenter.pendingintents and @@ -13,3 +16,4 @@ rule com.android.safetycenter.pendingintents.** com.android.permission.jarjar.@0 rule com.android.safetycenter.resources.** com.android.permission.jarjar.@0 rule com.google.protobuf.** com.android.permission.jarjar.@0 rule kotlin.** com.android.permission.jarjar.@0 +rule com.android.permissioncontroller.PermissionControllerStatsLog com.android.permission.jarjar.@0
\ No newline at end of file diff --git a/service/java/com/android/ecm/EnhancedConfirmationService.java b/service/java/com/android/ecm/EnhancedConfirmationService.java new file mode 100644 index 000000000..8558deb3c --- /dev/null +++ b/service/java/com/android/ecm/EnhancedConfirmationService.java @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ecm; + +import android.Manifest; +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.annotation.UserIdInt; +import android.app.AppOpsManager; +import android.app.ecm.EnhancedConfirmationManager; +import android.app.ecm.IEnhancedConfirmationManager; +import android.app.role.RoleManager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.InstallSourceInfo; +import android.content.pm.PackageInstaller; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.SignedPackage; +import android.os.Binder; +import android.os.Build; +import android.os.SystemConfigManager; +import android.os.UserHandle; +import android.permission.flags.Flags; +import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.Log; + +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; + +import com.android.internal.util.Preconditions; +import com.android.permission.util.UserUtils; +import com.android.server.SystemService; + +import java.lang.annotation.Retention; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * Service for ECM (Enhanced Confirmation Mode). + * + * @see EnhancedConfirmationManager + * + * @hide + */ +@Keep +@FlaggedApi(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) +@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) +public class EnhancedConfirmationService extends SystemService { + private static final String LOG_TAG = EnhancedConfirmationService.class.getSimpleName(); + + private Map<String, List<byte[]>> mTrustedPackageCertDigests; + private Map<String, List<byte[]>> mTrustedInstallerCertDigests; + + public EnhancedConfirmationService(@NonNull Context context) { + super(context); + } + + @Override + public void onStart() { + Context context = getContext(); + SystemConfigManager systemConfigManager = context.getSystemService( + SystemConfigManager.class); + mTrustedPackageCertDigests = toTrustedPackageMap( + systemConfigManager.getEnhancedConfirmationTrustedPackages()); + mTrustedInstallerCertDigests = toTrustedPackageMap( + systemConfigManager.getEnhancedConfirmationTrustedInstallers()); + + publishBinderService(Context.ECM_ENHANCED_CONFIRMATION_SERVICE, new Stub()); + } + + private Map<String, List<byte[]>> toTrustedPackageMap(Set<SignedPackage> signedPackages) { + ArrayMap<String, List<byte[]>> trustedPackageMap = new ArrayMap<>(); + for (SignedPackage signedPackage : signedPackages) { + ArrayList<byte[]> certDigests = (ArrayList<byte[]>) trustedPackageMap.computeIfAbsent( + signedPackage.getPackageName(), packageName -> new ArrayList<>(1)); + certDigests.add(signedPackage.getCertificateDigest()); + } + return trustedPackageMap; + } + + private class Stub extends IEnhancedConfirmationManager.Stub { + + /** A map of ECM states to their corresponding app op states */ + @Retention(java.lang.annotation.RetentionPolicy.SOURCE) + @IntDef(prefix = {"ECM_STATE_"}, value = {EcmState.ECM_STATE_NOT_GUARDED, + EcmState.ECM_STATE_GUARDED, EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED, + EcmState.ECM_STATE_IMPLICIT}) + private @interface EcmState { + int ECM_STATE_NOT_GUARDED = AppOpsManager.MODE_ALLOWED; + int ECM_STATE_GUARDED = AppOpsManager.MODE_ERRORED; + int ECM_STATE_GUARDED_AND_ACKNOWLEDGED = AppOpsManager.MODE_IGNORED; + int ECM_STATE_IMPLICIT = AppOpsManager.MODE_DEFAULT; + } + + private static final ArraySet<String> PROTECTED_SETTINGS = new ArraySet<>(); + + static { + // Runtime permissions + // TODO(b/310654818): Construct this list by permission group instead of by permission + PROTECTED_SETTINGS.add(Manifest.permission.READ_PHONE_STATE); + PROTECTED_SETTINGS.add(Manifest.permission.READ_PHONE_NUMBERS); + PROTECTED_SETTINGS.add(Manifest.permission.CALL_PHONE); + PROTECTED_SETTINGS.add(Manifest.permission.ADD_VOICEMAIL); + PROTECTED_SETTINGS.add(Manifest.permission.USE_SIP); + PROTECTED_SETTINGS.add(Manifest.permission.ANSWER_PHONE_CALLS); + PROTECTED_SETTINGS.add(Manifest.permission.ACCEPT_HANDOVER); + PROTECTED_SETTINGS.add(Manifest.permission_group.PHONE); + + PROTECTED_SETTINGS.add(Manifest.permission.SEND_SMS); + PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_SMS); + PROTECTED_SETTINGS.add(Manifest.permission.READ_SMS); + PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_MMS); + PROTECTED_SETTINGS.add(Manifest.permission.RECEIVE_WAP_PUSH); + PROTECTED_SETTINGS.add(Manifest.permission.READ_CELL_BROADCASTS); + PROTECTED_SETTINGS.add(Manifest.permission_group.SMS); + + PROTECTED_SETTINGS.add(Manifest.permission.BIND_DEVICE_ADMIN); + // TODO(b/310654818): Add other explicitly protected runtime permissions + // App ops + PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE); + PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS); + PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW); + PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_GET_USAGE_STATS); + PROTECTED_SETTINGS.add(AppOpsManager.OPSTR_LOADER_USAGE_STATS); + // Default application roles. + PROTECTED_SETTINGS.add(RoleManager.ROLE_DIALER); + PROTECTED_SETTINGS.add(RoleManager.ROLE_SMS); + // TODO(b/310654015): Add other explicitly protected settings + } + + private final @NonNull Context mContext; + private final String mAttributionTag; + private final AppOpsManager mAppOpsManager; + private final PackageManager mPackageManager; + + Stub() { + Context context = getContext(); + mContext = context; + mAttributionTag = context.getAttributionTag(); + mAppOpsManager = context.getSystemService(AppOpsManager.class); + mPackageManager = context.getPackageManager(); + } + + public boolean isRestricted(@NonNull String packageName, @NonNull String settingIdentifier, + @UserIdInt int userId) { + enforcePermissions("isRestricted", userId); + if (!UserUtils.isUserExistent(userId, getContext())) { + Log.e(LOG_TAG, "user " + userId + " does not exist"); + return false; + } + + Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); + Preconditions.checkStringNotEmpty(settingIdentifier, + "settingIdentifier cannot be null or empty"); + + try { + return isSettingEcmProtected(settingIdentifier) && isPackageEcmGuarded(packageName, + userId); + } catch (NameNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + + public void clearRestriction(@NonNull String packageName, @UserIdInt int userId) { + enforcePermissions("clearRestriction", userId); + if (!UserUtils.isUserExistent(userId, getContext())) { + return; + } + + Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); + + try { + int state = getAppEcmState(packageName, userId); + boolean isAllowed = state == EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED; + if (!isAllowed) { + throw new IllegalStateException("Clear restriction attempted but not allowed"); + } + setAppEcmState(packageName, EcmState.ECM_STATE_NOT_GUARDED, userId); + EnhancedConfirmationStatsLogUtils.INSTANCE.logRestrictionCleared( + getPackageUid(packageName, userId)); + } catch (NameNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + + public boolean isClearRestrictionAllowed(@NonNull String packageName, + @UserIdInt int userId) { + enforcePermissions("isClearRestrictionAllowed", userId); + if (!UserUtils.isUserExistent(userId, getContext())) { + return false; + } + + Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); + + try { + int state = getAppEcmState(packageName, userId); + return state == EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED; + } catch (NameNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + + public void setClearRestrictionAllowed(@NonNull String packageName, @UserIdInt int userId) { + enforcePermissions("setClearRestrictionAllowed", userId); + if (!UserUtils.isUserExistent(userId, getContext())) { + return; + } + + Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty"); + + try { + if (isPackageEcmGuarded(packageName, userId)) { + setAppEcmState(packageName, EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED, + userId); + } + } catch (NameNotFoundException e) { + throw new IllegalArgumentException(e); + } + } + + private void enforcePermissions(@NonNull String methodName, @UserIdInt int userId) { + UserUtils.enforceCrossUserPermission(userId, false, methodName, mContext); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES, methodName); + } + + private boolean isPackageEcmGuarded(@NonNull String packageName, @UserIdInt int userId) + throws NameNotFoundException { + ApplicationInfo applicationInfo = getApplicationInfoAsUser(packageName, userId); + // Always trust allow-listed and pre-installed packages + if (isAllowlistedPackage(packageName) || isAllowlistedInstaller(packageName) + || isPackagePreinstalled(applicationInfo)) { + return false; + } + + // If the package already has an explicitly-set state, use that + @EcmState int ecmState = getAppEcmState(packageName, userId); + if (ecmState == EcmState.ECM_STATE_GUARDED + || ecmState == EcmState.ECM_STATE_GUARDED_AND_ACKNOWLEDGED) { + return true; + } + if (ecmState == EcmState.ECM_STATE_NOT_GUARDED) { + return false; + } + + // Otherwise, lazily decide whether the app is considered guarded. + InstallSourceInfo installSource; + try { + installSource = mPackageManager.getInstallSourceInfo(packageName); + } catch (NameNotFoundException e) { + Log.w(LOG_TAG, "Package not found: " + packageName); + return false; + } + + // These install sources are always considered dangerous. + // PackageInstallers that are trusted can use these as a signal that the + // packages they've installed aren't as trusted as themselves. + int packageSource = installSource.getPackageSource(); + if (packageSource == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE + || packageSource == PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE) { + return true; + } + String installingPackageName = installSource.getInstallingPackageName(); + ApplicationInfo installingApplicationInfo = + getApplicationInfoAsUser(installingPackageName, userId); + // TODO(b/330927429): We might need a long-term solution to persist the installer's + // targetSdkVersion if it is uninstalled. + if (packageSource == PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED + && installingApplicationInfo != null + && installingApplicationInfo.targetSdkVersion + >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { + return true; + } + + // ECM doesn't consider a transitive chain of trust for install sources. + // If this package hasn't been explicitly handled by this point + // then it is exempt from ECM if the immediate parent is a trusted installer + return !(trustPackagesInstalledViaNonAllowlistedInstallers() + || isPackagePreinstalled(installingApplicationInfo) + || isAllowlistedInstaller(installingPackageName)); + } + + private boolean isAllowlistedPackage(String packageName) { + return isPackageSignedWithAnyOf(packageName, + mTrustedPackageCertDigests.get(packageName)); + } + + private boolean isAllowlistedInstaller(String packageName) { + return isPackageSignedWithAnyOf(packageName, + mTrustedInstallerCertDigests.get(packageName)); + } + + private boolean isPackageSignedWithAnyOf(String packageName, List<byte[]> certDigests) { + if (packageName != null && certDigests != null) { + for (int i = 0, count = certDigests.size(); i < count; i++) { + byte[] trustedCertDigest = certDigests.get(i); + if (mPackageManager.hasSigningCertificate(packageName, trustedCertDigest, + PackageManager.CERT_INPUT_SHA256)) { + return true; + } + } + } + return false; + } + + /** + * @return {@code true} if zero {@code <enhanced-confirmation-trusted-installer>} entries + * are defined in {@code frameworks/base/data/etc/enhanced-confirmation.xml}; in this case, + * we treat all installers as trusted. + */ + private boolean trustPackagesInstalledViaNonAllowlistedInstallers() { + return mTrustedInstallerCertDigests.isEmpty(); + } + + private boolean isPackagePreinstalled(@Nullable ApplicationInfo applicationInfo) { + if (applicationInfo == null) { + return false; + } + return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + } + + private void setAppEcmState(@NonNull String packageName, @EcmState int ecmState, + @UserIdInt int userId) throws NameNotFoundException { + int packageUid = getPackageUid(packageName, userId); + final long identityToken = Binder.clearCallingIdentity(); + try { + mAppOpsManager.setMode(AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, packageUid, + packageName, ecmState); + } finally { + Binder.restoreCallingIdentity(identityToken); + } + } + + private @EcmState int getAppEcmState(@NonNull String packageName, @UserIdInt int userId) + throws NameNotFoundException { + int packageUid = getPackageUid(packageName, userId); + final long identityToken = Binder.clearCallingIdentity(); + try { + return mAppOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, + packageUid, packageName, mAttributionTag, /* message */ null); + } finally { + Binder.restoreCallingIdentity(identityToken); + } + } + + private boolean isSettingEcmProtected(@NonNull String settingIdentifier) { + if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) + || mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH) + || mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + return false; + } + + if (PROTECTED_SETTINGS.contains(settingIdentifier)) { + return true; + } + // TODO(b/310218979): Add role selections as protected settings + return false; + } + + @Nullable + private ApplicationInfo getApplicationInfoAsUser(@Nullable String packageName, + @UserIdInt int userId) { + if (packageName == null) { + Log.w(LOG_TAG, "The packageName should not be null."); + return null; + } + try { + return mPackageManager.getApplicationInfoAsUser(packageName, /* flags */ 0, + UserHandle.of(userId)); + } catch (NameNotFoundException e) { + Log.w(LOG_TAG, "Package not found: " + packageName, e); + return null; + } + } + + private int getPackageUid(@NonNull String packageName, @UserIdInt int userId) + throws NameNotFoundException { + return mPackageManager.getApplicationInfoAsUser(packageName, /* flags */ 0, + UserHandle.of(userId)).uid; + } + } +} diff --git a/service/java/com/android/ecm/EnhancedConfirmationStatsLogUtils.kt b/service/java/com/android/ecm/EnhancedConfirmationStatsLogUtils.kt new file mode 100644 index 000000000..5bf925fc7 --- /dev/null +++ b/service/java/com/android/ecm/EnhancedConfirmationStatsLogUtils.kt @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ecm + +import android.permission.flags.Flags +import android.util.Log +import com.android.internal.annotations.Keep +import com.android.modules.utils.build.SdkLevel +import com.android.permissioncontroller.PermissionControllerStatsLog + +/** + * Provides ECM-related metrics logging for Permission APEX services. + * + * @hide + */ +@Keep +object EnhancedConfirmationStatsLogUtils { + private val LOG_TAG = EnhancedConfirmationStatsLogUtils::class.java.simpleName + + fun logRestrictionCleared(uid: Int) { + if (!SdkLevel.isAtLeastV() || !Flags.enhancedConfirmationModeApisEnabled()) { + return + } + Log.v(LOG_TAG, "ENHANCED_CONFIRMATION_RESTRICTION_CLEARED: uid='$uid'") + + PermissionControllerStatsLog.write( + PermissionControllerStatsLog.ENHANCED_CONFIRMATION_RESTRICTION_CLEARED, + uid + ) + } +} diff --git a/service/java/com/android/permission/util/UserUtils.java b/service/java/com/android/permission/util/UserUtils.java index 8205be239..33389a88f 100644 --- a/service/java/com/android/permission/util/UserUtils.java +++ b/service/java/com/android/permission/util/UserUtils.java @@ -25,7 +25,9 @@ import android.os.UserHandle; import android.os.UserManager; import com.android.internal.util.Preconditions; +import com.android.modules.utils.build.SdkLevel; import com.android.permission.compat.UserHandleCompat; +import com.android.permission.flags.Flags; import java.util.List; @@ -92,6 +94,39 @@ public final class UserUtils { } /** + * Returns whether the given {@code userId} is a private profile. Note that private profiles are + * allowed from Android V+ only, so this method will return false on Sdk levels below that. + */ + public static boolean isPrivateProfile(@UserIdInt int userId, @NonNull Context context) { + if (!isPrivateProfileSupported()) { + return false; + } + // It's needed to clear the calling identity because we are going to query the UserManager + // for isPrivateProfile() and Context for createContextAsUser, which requires one of the + // following permissions: + // MANAGE_USERS, QUERY_USERS, or INTERACT_ACROSS_USERS. + final long identity = Binder.clearCallingIdentity(); + try { + Context userContext = context + .createContextAsUser(UserHandle.of(userId), /* flags= */ 0); + UserManager userManager = userContext.getSystemService(UserManager.class); + return userManager != null && userManager.isPrivateProfile(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + + /** + * Returns whether private profile's allowed to exist. This can be true iff the SdkLevel is at + * least V AND the permission module's private profile feature flag is enabled. + */ + public static boolean isPrivateProfileSupported() { + //TODO(b/286539356) add the os feature flag protection when available. + return SdkLevel.isAtLeastV() && Flags.privateProfileSupported(); + } + + /** * Returns whether a given {@code userId} corresponds to a running managed profile, i.e. the * user is running and the quiet mode is not enabled. */ diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java index 2524627eb..8348d4064 100644 --- a/service/java/com/android/role/RoleService.java +++ b/service/java/com/android/role/RoleService.java @@ -100,15 +100,22 @@ public class RoleService extends SystemService implements RoleUserState.Callback private static final long GRANT_DEFAULT_ROLES_INTERVAL_MILLIS = 1000; - private static final String[] DEFAULT_APPLICATION_ROLES = { - RoleManager.ROLE_ASSISTANT, - RoleManager.ROLE_BROWSER, - RoleManager.ROLE_CALL_REDIRECTION, - RoleManager.ROLE_CALL_SCREENING, - RoleManager.ROLE_DIALER, - RoleManager.ROLE_HOME, - RoleManager.ROLE_SMS, - }; + private static final String[] DEFAULT_APPLICATION_ROLES; + + static { + List<String> defaultApplicationRoles = new ArrayList<>(); + defaultApplicationRoles.add(RoleManager.ROLE_ASSISTANT); + defaultApplicationRoles.add(RoleManager.ROLE_BROWSER); + defaultApplicationRoles.add(RoleManager.ROLE_CALL_REDIRECTION); + defaultApplicationRoles.add(RoleManager.ROLE_CALL_SCREENING); + defaultApplicationRoles.add(RoleManager.ROLE_DIALER); + defaultApplicationRoles.add(RoleManager.ROLE_HOME); + defaultApplicationRoles.add(RoleManager.ROLE_SMS); + if (SdkLevel.isAtLeastV()) { + defaultApplicationRoles.add(RoleManager.ROLE_WALLET); + } + DEFAULT_APPLICATION_ROLES = defaultApplicationRoles.toArray(new String[0]); + } @NonNull private final AppOpsManager mAppOpsManager; @@ -313,6 +320,11 @@ public class RoleService extends SystemService implements RoleUserState.Callback @AnyThread @NonNull private AndroidFuture<Void> maybeGrantDefaultRolesInternal(@UserIdInt int userId) { + if (!UserUtils.isUserExistent(userId, getContext())) { + Log.w(LOG_TAG, "User " + userId + " does not exist"); + return AndroidFuture.completedFuture(null); + } + RoleUserState userState = getOrCreateUserState(userId); String oldPackagesHash = userState.getPackagesHash(); String newPackagesHash = mPlatformHelper.computePackageStateHash(userId); @@ -923,6 +935,33 @@ public class RoleService extends SystemService implements RoleUserState.Callback } @Override + public String getEmergencyRoleHolder(int userId) { + final Context context = getContext(); + UserUtils.enforceCrossUserPermission(userId, false, "getEmergencyRoleHolder", context); + if (!UserUtils.isUserExistent(userId, getContext())) { + Log.e(LOG_TAG, "user " + userId + " does not exist"); + return null; + } + + getContext().enforceCallingOrSelfPermission( + Manifest.permission.READ_PRIVILEGED_PHONE_STATE, "getEmergencyRoleHolder"); + + final String packageName; + final long identity = Binder.clearCallingIdentity(); + try { + packageName = CollectionUtils.firstOrNull(getRoleHoldersAsUser( + RoleManager.ROLE_EMERGENCY, userId)); + } finally { + Binder.restoreCallingIdentity(identity); + } + if (packageName != null && !PackageUtils.canCallingOrSelfPackageQuery(packageName, + userId, context)) { + return null; + } + return packageName; + } + + @Override public boolean isRoleVisibleAsUser(@NonNull String roleName, @UserIdInt int userId) { UserUtils.enforceCrossUserPermission(userId, false, "isRoleVisibleAsUser", getContext()); diff --git a/service/java/com/android/safetycenter/SafetyCenterBroadcastDispatcher.java b/service/java/com/android/safetycenter/SafetyCenterBroadcastDispatcher.java index a36beb2d3..5c9dfa664 100644 --- a/service/java/com/android/safetycenter/SafetyCenterBroadcastDispatcher.java +++ b/service/java/com/android/safetycenter/SafetyCenterBroadcastDispatcher.java @@ -49,6 +49,7 @@ import androidx.annotation.Nullable; import com.android.permission.util.PackageUtils; import com.android.safetycenter.SafetyCenterConfigReader.Broadcast; +import com.android.safetycenter.UserProfileGroup.ProfileType; import com.android.safetycenter.data.SafetyCenterDataManager; import java.time.Duration; @@ -334,37 +335,35 @@ final class SafetyCenterBroadcastDispatcher { * lists of source IDs. * * <p>The set of user IDs (keys) is the profile parent user ID of {@code userProfileGroup} plus - * the (possibly empty) set of running managed profile user IDs in that group. - * + * all the other types of running profiles: + * <ol> + * <li>The (possibly empty) set of running managed profile user IDs in that group. + * <li>The (possibly empty) set of running private profile user ID in that group. + * </ol> * <p>Every value present is a non-empty list, but the overall result may be empty. */ private SparseArray<List<String>> getUserIdsToSourceIds( Broadcast broadcast, UserProfileGroup userProfileGroup, @RefreshReason int refreshReason) { - int[] managedProfileIds = userProfileGroup.getManagedRunningProfilesUserIds(); - SparseArray<List<String>> result = new SparseArray<>(managedProfileIds.length + 1); - List<String> profileParentSources = - getSourceIdsForRefreshReason( - refreshReason, - broadcast.getSourceIdsForProfileParent(), - broadcast.getSourceIdsForProfileParentOnPageOpen(), - userProfileGroup.getProfileParentUserId()); - - if (!profileParentSources.isEmpty()) { - result.put(userProfileGroup.getProfileParentUserId(), profileParentSources); - } - - for (int i = 0; i < managedProfileIds.length; i++) { - List<String> managedProfileSources = - getSourceIdsForRefreshReason( - refreshReason, - broadcast.getSourceIdsForManagedProfiles(), - broadcast.getSourceIdsForManagedProfilesOnPageOpen(), - managedProfileIds[i]); - - if (!managedProfileSources.isEmpty()) { - result.put(managedProfileIds[i], managedProfileSources); + SparseArray<List<String>> result = + new SparseArray<>(userProfileGroup.getNumRunningProfiles()); + for (int profilTypeIdx = 0; + profilTypeIdx < ProfileType.ALL_PROFILE_TYPES.length; + ++profilTypeIdx) { + @ProfileType int profileType = ProfileType.ALL_PROFILE_TYPES[profilTypeIdx]; + int[] runningProfiles = userProfileGroup.getRunningProfilesOfType(profileType); + for (int profileIdx = 0; profileIdx < runningProfiles.length; ++profileIdx) { + List<String> profileSources = + getSourceIdsForRefreshReason( + refreshReason, + broadcast.getSourceIdsForProfileType(profileType), + broadcast.getSourceIdsOnPageOpenForProfileType(profileType), + runningProfiles[profileIdx]); + + if (!profileSources.isEmpty()) { + result.put(runningProfiles[profileIdx], profileSources); + } } } diff --git a/service/java/com/android/safetycenter/SafetyCenterConfigReader.java b/service/java/com/android/safetycenter/SafetyCenterConfigReader.java index c473ad916..641c242f1 100644 --- a/service/java/com/android/safetycenter/SafetyCenterConfigReader.java +++ b/service/java/com/android/safetycenter/SafetyCenterConfigReader.java @@ -16,6 +16,11 @@ package com.android.safetycenter; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_MANAGED; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_PRIMARY; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_PRIVATE; + +import static java.util.Collections.emptyList; import static java.util.Collections.unmodifiableList; import static java.util.Objects.requireNonNull; @@ -28,6 +33,7 @@ import android.util.Log; import androidx.annotation.Nullable; +import com.android.safetycenter.UserProfileGroup.ProfileType; import com.android.safetycenter.config.ParseException; import com.android.safetycenter.config.SafetyCenterConfigParser; import com.android.safetycenter.resources.SafetyCenterResourcesApk; @@ -410,7 +416,7 @@ public final class SafetyCenterConfigReader { broadcast.mSourceIdsForProfileParentOnPageOpen.add(safetySource.getId()); } boolean needsManagedProfilesBroadcast = - SafetySources.supportsManagedProfiles(safetySource); + SafetySources.supportsProfileType(safetySource, PROFILE_TYPE_MANAGED); if (needsManagedProfilesBroadcast) { broadcast.mSourceIdsForManagedProfiles.add(safetySource.getId()); if (safetySource.isRefreshOnPageOpenAllowed()) { @@ -418,6 +424,19 @@ public final class SafetyCenterConfigReader { safetySource.getId()); } } + + // TODO(b/317378205): think about generalising these fields in Broadcast so that + // we are not duplicating the code - it can be a source of confusion and errors + // in future. + boolean needsPrivateProfileBroadcast = + SafetySources.supportsProfileType(safetySource, PROFILE_TYPE_PRIVATE); + if (needsPrivateProfileBroadcast) { + broadcast.mSourceIdsForPrivateProfile.add(safetySource.getId()); + if (safetySource.isRefreshOnPageOpenAllowed()) { + broadcast.mSourceIdsForPrivateProfileOnPageOpen.add( + safetySource.getId()); + } + } } } @@ -486,6 +505,8 @@ public final class SafetyCenterConfigReader { private final List<String> mSourceIdsForProfileParentOnPageOpen = new ArrayList<>(); private final List<String> mSourceIdsForManagedProfiles = new ArrayList<>(); private final List<String> mSourceIdsForManagedProfilesOnPageOpen = new ArrayList<>(); + private final List<String> mSourceIdsForPrivateProfile = new ArrayList<>(); + private final List<String> mSourceIdsForPrivateProfileOnPageOpen = new ArrayList<>(); private Broadcast(String packageName) { mPackageName = packageName; @@ -497,41 +518,42 @@ public final class SafetyCenterConfigReader { } /** - * Returns the safety source ids associated with this broadcast in the profile owner. - * - * <p>If this list is empty, there are no sources to dispatch to in the profile owner. - */ - List<String> getSourceIdsForProfileParent() { - return unmodifiableList(mSourceIdsForProfileParent); - } - - /** - * Returns the safety source ids associated with this broadcast in the profile owner that - * have refreshOnPageOpenAllowed set to true in the XML config. + * Returns the safety source ids associated with this broadcast in the given profile type. * - * <p>If this list is empty, there are no sources to dispatch to in the profile owner. + * <p>If this list is empty, there are no sources to dispatch to in the given profile type. */ - List<String> getSourceIdsForProfileParentOnPageOpen() { - return unmodifiableList(mSourceIdsForProfileParentOnPageOpen); - } - - /** - * Returns the safety source ids associated with this broadcast in the managed profile(s). - * - * <p>If this list is empty, there are no sources to dispatch to in the managed profile(s). - */ - List<String> getSourceIdsForManagedProfiles() { - return unmodifiableList(mSourceIdsForManagedProfiles); + List<String> getSourceIdsForProfileType(@ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return unmodifiableList(mSourceIdsForProfileParent); + case PROFILE_TYPE_MANAGED: + return unmodifiableList(mSourceIdsForManagedProfiles); + case PROFILE_TYPE_PRIVATE: + return unmodifiableList(mSourceIdsForPrivateProfile); + default: + Log.w(TAG, "source ids asked for unexpected profile " + profileType); + return emptyList(); + } } /** - * Returns the safety source ids associated with this broadcast in the managed profile(s) + * Returns the safety source ids associated with this broadcast in the given profile type * that have refreshOnPageOpenAllowed set to true in the XML config. * - * <p>If this list is empty, there are no sources to dispatch to in the managed profile(s). + * <p>If this list is empty, there are no sources to dispatch to in the given profile type. */ - List<String> getSourceIdsForManagedProfilesOnPageOpen() { - return unmodifiableList(mSourceIdsForManagedProfilesOnPageOpen); + List<String> getSourceIdsOnPageOpenForProfileType(@ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return unmodifiableList(mSourceIdsForProfileParentOnPageOpen); + case PROFILE_TYPE_MANAGED: + return unmodifiableList(mSourceIdsForManagedProfilesOnPageOpen); + case PROFILE_TYPE_PRIVATE: + return unmodifiableList(mSourceIdsForPrivateProfileOnPageOpen); + default: + Log.w(TAG, "source ids asked for unexpected profile " + profileType); + return emptyList(); + } } @Override @@ -545,7 +567,10 @@ public final class SafetyCenterConfigReader { that.mSourceIdsForProfileParentOnPageOpen) && mSourceIdsForManagedProfiles.equals(that.mSourceIdsForManagedProfiles) && mSourceIdsForManagedProfilesOnPageOpen.equals( - that.mSourceIdsForManagedProfilesOnPageOpen); + that.mSourceIdsForManagedProfilesOnPageOpen) + && mSourceIdsForPrivateProfile.equals(that.mSourceIdsForPrivateProfile) + && mSourceIdsForPrivateProfileOnPageOpen.equals( + that.mSourceIdsForPrivateProfileOnPageOpen); } @Override @@ -555,7 +580,9 @@ public final class SafetyCenterConfigReader { mSourceIdsForProfileParent, mSourceIdsForProfileParentOnPageOpen, mSourceIdsForManagedProfiles, - mSourceIdsForManagedProfilesOnPageOpen); + mSourceIdsForManagedProfilesOnPageOpen, + mSourceIdsForPrivateProfile, + mSourceIdsForPrivateProfileOnPageOpen); } @Override @@ -571,6 +598,10 @@ public final class SafetyCenterConfigReader { + mSourceIdsForManagedProfiles + ", mSourceIdsForManagedProfilesOnPageOpen=" + mSourceIdsForManagedProfilesOnPageOpen + + ", mSourceIdsForPrivateProfile=" + + mSourceIdsForPrivateProfile + + ", mSourceIdsForPrivateProfileOnPageOpen=" + + mSourceIdsForPrivateProfileOnPageOpen + '}'; } } diff --git a/service/java/com/android/safetycenter/SafetyCenterDataFactory.java b/service/java/com/android/safetycenter/SafetyCenterDataFactory.java index d74d160f4..7c7ade3f1 100644 --- a/service/java/com/android/safetycenter/SafetyCenterDataFactory.java +++ b/service/java/com/android/safetycenter/SafetyCenterDataFactory.java @@ -17,7 +17,11 @@ package com.android.safetycenter; import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; +import static android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_MANAGED; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_PRIMARY; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_PRIVATE; import static com.android.safetycenter.internaldata.SafetyCenterBundles.ISSUES_TO_GROUPS_BUNDLE_KEY; import static com.android.safetycenter.internaldata.SafetyCenterBundles.STATIC_ENTRIES_TO_IDS_BUNDLE_KEY; @@ -53,7 +57,8 @@ import android.util.Log; import androidx.annotation.Nullable; import com.android.modules.utils.build.SdkLevel; -import com.android.permission.util.UserUtils; +import com.android.permission.flags.Flags; +import com.android.safetycenter.UserProfileGroup.ProfileType; import com.android.safetycenter.data.SafetyCenterDataManager; import com.android.safetycenter.internaldata.SafetyCenterBundles; import com.android.safetycenter.internaldata.SafetyCenterEntryId; @@ -387,42 +392,36 @@ public final class SafetyCenterDataFactory { List<SafetySource> safetySources = safetySourcesGroup.getSafetySources(); List<SafetyCenterEntry> entries = new ArrayList<>(safetySources.size()); - for (int i = 0; i < safetySources.size(); i++) { - SafetySource safetySource = safetySources.get(i); - - groupSafetyCenterEntryLevel = - mergeSafetyCenterEntrySeverityLevels( - groupSafetyCenterEntryLevel, - addSafetyCenterEntry( - safetyCenterOverallState, - entries, - safetySource, - defaultPackageName, - userProfileGroup.getProfileParentUserId(), - /* isUserManaged= */ false, - /* isManagedUserRunning= */ false)); - - if (!SafetySources.supportsManagedProfiles(safetySource)) { - continue; - } - - int[] managedProfilesUserIds = userProfileGroup.getManagedProfilesUserIds(); - for (int j = 0; j < managedProfilesUserIds.length; j++) { - int managedProfileUserId = managedProfilesUserIds[j]; - boolean isManagedUserRunning = - userProfileGroup.isManagedUserRunning(managedProfileUserId); + for (int safetySourceIdx = 0; safetySourceIdx < safetySources.size(); ++safetySourceIdx) { + SafetySource safetySource = safetySources.get(safetySourceIdx); + for (int profileTypeIdx = 0; + profileTypeIdx < ProfileType.ALL_PROFILE_TYPES.length; + ++profileTypeIdx) { + @ProfileType int profileType = ProfileType.ALL_PROFILE_TYPES[profileTypeIdx]; + if (!SafetySources.supportsProfileType(safetySource, profileType)) { + continue; + } - groupSafetyCenterEntryLevel = - mergeSafetyCenterEntrySeverityLevels( - groupSafetyCenterEntryLevel, - addSafetyCenterEntry( - safetyCenterOverallState, - entries, - safetySource, - defaultPackageName, - managedProfileUserId, - /* isUserManaged= */ true, - isManagedUserRunning)); + int[] profileIds = userProfileGroup.getProfilesOfType(profileType); + for (int profileIdx = 0; profileIdx < profileIds.length; profileIdx++) { + int profileId = profileIds[profileIdx]; + boolean isUserRunning = + userProfileGroup.containsRunningUserId(profileId, profileType); + if (profileType == PROFILE_TYPE_PRIVATE && !isUserRunning) { + continue; + } + groupSafetyCenterEntryLevel = + mergeSafetyCenterEntrySeverityLevels( + groupSafetyCenterEntryLevel, + addSafetyCenterEntry( + safetyCenterOverallState, + entries, + safetySource, + defaultPackageName, + profileId, + profileType, + isUserRunning)); + } } } @@ -534,7 +533,8 @@ public final class SafetyCenterDataFactory { SafetyCenterEntry entry = entries.get(i); SafetyCenterEntryId entryId = SafetyCenterIds.entryIdFromString(entry.getId()); - if (UserUtils.isManagedProfile(entryId.getUserId(), mContext)) { + if (UserProfileGroup.getProfileTypeOfUser(entryId.getUserId(), mContext) + != PROFILE_TYPE_PRIMARY) { continue; } @@ -558,15 +558,15 @@ public final class SafetyCenterDataFactory { SafetySource safetySource, String defaultPackageName, @UserIdInt int userId, - boolean isUserManaged, - boolean isManagedUserRunning) { + @ProfileType int profileType, + boolean isUserRunning) { SafetyCenterEntry safetyCenterEntry = toSafetyCenterEntry( safetySource, defaultPackageName, userId, - isUserManaged, - isManagedUserRunning); + profileType, + isUserRunning); if (safetyCenterEntry == null) { return SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNSPECIFIED; } @@ -584,8 +584,8 @@ public final class SafetyCenterDataFactory { SafetySource safetySource, String defaultPackageName, @UserIdInt int userId, - boolean isUserManaged, - boolean isManagedUserRunning) { + @ProfileType int profileType, + boolean isUserRunning) { switch (safetySource.getType()) { case SafetySource.SAFETY_SOURCE_TYPE_ISSUE_ONLY: return null; @@ -594,7 +594,7 @@ public final class SafetyCenterDataFactory { SafetySourceStatus safetySourceStatus = getSafetySourceStatus( mSafetyCenterDataManager.getSafetySourceDataInternal(key)); - boolean inQuietMode = isUserManaged && !isManagedUserRunning; + boolean inQuietMode = (PROFILE_TYPE_MANAGED == profileType) && !isUserRunning; if (safetySourceStatus == null) { int severityLevel = inQuietMode @@ -606,8 +606,8 @@ public final class SafetyCenterDataFactory { severityLevel, SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION, userId, - isUserManaged, - isManagedUserRunning); + profileType, + isUserRunning); } PendingIntent sourceProvidedPendingIntent = inQuietMode ? null : safetySourceStatus.getPendingIntent(); @@ -665,8 +665,8 @@ public final class SafetyCenterDataFactory { SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_UNSPECIFIED, SafetyCenterEntry.SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON, userId, - isUserManaged, - isManagedUserRunning); + profileType, + isUserRunning); } Log.w( TAG, @@ -681,8 +681,8 @@ public final class SafetyCenterDataFactory { @SafetyCenterEntry.EntrySeverityLevel int entrySeverityLevel, @SafetyCenterEntry.SeverityUnspecifiedIconType int severityUnspecifiedIconType, @UserIdInt int userId, - boolean isUserManaged, - boolean isManagedUserRunning) { + @ProfileType int profileType, + boolean isUserRunning) { if (SafetySources.isDefaultEntryHidden(safetySource)) { return null; } @@ -692,7 +692,7 @@ public final class SafetyCenterDataFactory { .setSafetySourceId(safetySource.getId()) .setUserId(userId) .build(); - boolean isQuietModeEnabled = isUserManaged && !isManagedUserRunning; + boolean isQuietModeEnabled = (PROFILE_TYPE_MANAGED == profileType) && !isUserRunning; PendingIntent pendingIntent = mPendingIntentFactory.getPendingIntent( safetySource.getId(), @@ -702,13 +702,7 @@ public final class SafetyCenterDataFactory { isQuietModeEnabled); boolean enabled = pendingIntent != null && !SafetySources.isDefaultEntryDisabled(safetySource); - CharSequence title = - isUserManaged - ? DevicePolicyResources.getSafetySourceWorkString( - mSafetyCenterResourcesApk, - safetySource.getId(), - safetySource.getTitleForWorkResId()) - : mSafetyCenterResourcesApk.getString(safetySource.getTitleResId()); + CharSequence title = getTitleForProfileType(profileType, safetySource); CharSequence summary = mSafetyCenterDataManager.sourceHasError( SafetySourceKey.of(safetySource.getId(), userId)) @@ -738,38 +732,33 @@ public final class SafetyCenterDataFactory { UserProfileGroup userProfileGroup) { List<SafetySource> safetySources = safetySourcesGroup.getSafetySources(); List<SafetyCenterStaticEntry> staticEntries = new ArrayList<>(safetySources.size()); - for (int i = 0; i < safetySources.size(); i++) { - SafetySource safetySource = safetySources.get(i); - - addSafetyCenterStaticEntry( - staticEntriesToIds, - safetyCenterOverallState, - staticEntries, - safetySource, - defaultPackageName, - userProfileGroup.getProfileParentUserId(), - /* isUserManaged= */ false, - /* isManagedUserRunning= */ false); - - if (!SafetySources.supportsManagedProfiles(safetySource)) { - continue; - } - - int[] managedProfilesUserIds = userProfileGroup.getManagedProfilesUserIds(); - for (int j = 0; j < managedProfilesUserIds.length; j++) { - int managedProfileUserId = managedProfilesUserIds[j]; - boolean isManagedUserRunning = - userProfileGroup.isManagedUserRunning(managedProfileUserId); - - addSafetyCenterStaticEntry( - staticEntriesToIds, - safetyCenterOverallState, - staticEntries, - safetySource, - defaultPackageName, - managedProfileUserId, - /* isUserManaged= */ true, - isManagedUserRunning); + for (int safetySourceIdx = 0; safetySourceIdx < safetySources.size(); safetySourceIdx++) { + SafetySource safetySource = safetySources.get(safetySourceIdx); + for (int profileTypeIdx = 0; + profileTypeIdx < ProfileType.ALL_PROFILE_TYPES.length; + ++profileTypeIdx) { + @ProfileType int profileType = ProfileType.ALL_PROFILE_TYPES[profileTypeIdx]; + if (!SafetySources.supportsProfileType(safetySource, profileType)) { + continue; + } + int[] profileIds = userProfileGroup.getProfilesOfType(profileType); + for (int profileIdx = 0; profileIdx < profileIds.length; ++profileIdx) { + int profileId = profileIds[profileIdx]; + boolean isUserRunning = + userProfileGroup.containsRunningUserId(profileId, profileType); + if (profileType == PROFILE_TYPE_PRIVATE && !isUserRunning) { + continue; + } + addSafetyCenterStaticEntry( + staticEntriesToIds, + safetyCenterOverallState, + staticEntries, + safetySource, + defaultPackageName, + profileId, + profileType, + isUserRunning); + } } } @@ -790,15 +779,15 @@ public final class SafetyCenterDataFactory { SafetySource safetySource, String defaultPackageName, @UserIdInt int userId, - boolean isUserManaged, - boolean isManagedUserRunning) { + @ProfileType int profileType, + boolean isUserRunning) { SafetyCenterStaticEntry staticEntry = toSafetyCenterStaticEntry( safetySource, defaultPackageName, userId, - isUserManaged, - isManagedUserRunning); + profileType, + isUserRunning); if (staticEntry == null) { return; } @@ -826,8 +815,8 @@ public final class SafetyCenterDataFactory { SafetySource safetySource, String defaultPackageName, @UserIdInt int userId, - boolean isUserManaged, - boolean isManagedUserRunning) { + @ProfileType int profileType, + boolean isUserRunning) { switch (safetySource.getType()) { case SafetySource.SAFETY_SOURCE_TYPE_ISSUE_ONLY: return null; @@ -836,7 +825,7 @@ public final class SafetyCenterDataFactory { SafetySourceStatus safetySourceStatus = getSafetySourceStatus( mSafetyCenterDataManager.getSafetySourceDataInternal(key)); - boolean inQuietMode = isUserManaged && !isManagedUserRunning; + boolean inQuietMode = (profileType == PROFILE_TYPE_MANAGED) && !isUserRunning; if (safetySourceStatus != null) { PendingIntent sourceProvidedPendingIntent = inQuietMode ? null : safetySourceStatus.getPendingIntent(); @@ -867,15 +856,15 @@ public final class SafetyCenterDataFactory { safetySource, safetySource.getPackageName(), userId, - isUserManaged, - isManagedUserRunning); + profileType, + isUserRunning); case SafetySource.SAFETY_SOURCE_TYPE_STATIC: return toDefaultSafetyCenterStaticEntry( safetySource, getStaticSourcePackageNameOrDefault(safetySource, defaultPackageName), userId, - isUserManaged, - isManagedUserRunning); + profileType, + isUserRunning); } Log.w(TAG, "Unknown safety source type found in rigid group: " + safetySource.getType()); return null; @@ -886,12 +875,12 @@ public final class SafetyCenterDataFactory { SafetySource safetySource, String packageName, @UserIdInt int userId, - boolean isUserManaged, - boolean isManagedUserRunning) { + @ProfileType int profileType, + boolean isUserRunning) { if (SafetySources.isDefaultEntryHidden(safetySource)) { return null; } - boolean isQuietModeEnabled = isUserManaged && !isManagedUserRunning; + boolean isQuietModeEnabled = (profileType == PROFILE_TYPE_MANAGED) && !isUserRunning; PendingIntent pendingIntent = mPendingIntentFactory.getPendingIntent( safetySource.getId(), @@ -905,13 +894,7 @@ public final class SafetyCenterDataFactory { return null; } - CharSequence title = - isUserManaged - ? DevicePolicyResources.getSafetySourceWorkString( - mSafetyCenterResourcesApk, - safetySource.getId(), - safetySource.getTitleForWorkResId()) - : mSafetyCenterResourcesApk.getString(safetySource.getTitleResId()); + CharSequence title = getTitleForProfileType(profileType, safetySource); CharSequence summary = mSafetyCenterDataManager.sourceHasError( SafetySourceKey.of(safetySource.getId(), userId)) @@ -1242,6 +1225,29 @@ public final class SafetyCenterDataFactory { return null; } + private CharSequence getTitleForProfileType( + @ProfileType int profileType, SafetySource safetySource) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return mSafetyCenterResourcesApk.getString(safetySource.getTitleResId()); + case PROFILE_TYPE_MANAGED: + return DevicePolicyResources.getSafetySourceWorkString( + mSafetyCenterResourcesApk, + safetySource.getId(), + safetySource.getTitleForWorkResId()); + case PROFILE_TYPE_PRIVATE: + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + return mSafetyCenterResourcesApk.getString( + safetySource.getTitleForPrivateProfileResId()); + } + Log.w(TAG, "unsupported private profile type encountered"); + return mSafetyCenterResourcesApk.getString(safetySource.getTitleResId()); + default: + Log.w(TAG, "unexpected value for the profile type " + profileType); + return mSafetyCenterResourcesApk.getString(safetySource.getTitleResId()); + } + } + private static SafetySourceKey toSafetySourceKey(String safetyCenterEntryIdString) { SafetyCenterEntryId id = SafetyCenterIds.entryIdFromString(safetyCenterEntryIdString); return SafetySourceKey.of(id.getSafetySourceId(), id.getUserId()); diff --git a/service/java/com/android/safetycenter/SafetyCenterFlags.java b/service/java/com/android/safetycenter/SafetyCenterFlags.java index 67c4d25d6..e51d3a1cf 100644 --- a/service/java/com/android/safetycenter/SafetyCenterFlags.java +++ b/service/java/com/android/safetycenter/SafetyCenterFlags.java @@ -123,6 +123,9 @@ public final class SafetyCenterFlags { private static final String RESURFACE_ISSUE_DELAYS_DEFAULT = ""; private static final Duration RESURFACE_ISSUE_DELAYS_DEFAULT_DURATION = Duration.ofDays(180); + private static final ArraySet<String> sAllowedNotificationSourcesUPlus = + new ArraySet<>(new String[] {"GoogleBackupAndRestore"}); + private static volatile String sUntrackedSourcesDefault = "AndroidAccessibility,AndroidBackgroundLocation," + "AndroidNotificationListener,AndroidPermissionAutoRevoke"; @@ -175,7 +178,10 @@ public final class SafetyCenterFlags { fout.println("FLAGS"); printFlag(fout, PROPERTY_SAFETY_CENTER_ENABLED, getSafetyCenterEnabled()); printFlag(fout, PROPERTY_NOTIFICATIONS_ENABLED, getNotificationsEnabled()); - printFlag(fout, PROPERTY_NOTIFICATIONS_ALLOWED_SOURCES, getNotificationsAllowedSourceIds()); + printFlag( + fout, + PROPERTY_NOTIFICATIONS_ALLOWED_SOURCES, + getNotificationsAllowedSourceIdsFlag()); printFlag(fout, PROPERTY_NOTIFICATIONS_MIN_DELAY, getNotificationsMinDelay()); printFlag( fout, @@ -244,6 +250,20 @@ public final class SafetyCenterFlags { * and therefore this is the only way to enable notifications for sources on Android T. */ public static ArraySet<String> getNotificationsAllowedSourceIds() { + ArraySet<String> sources = getNotificationsAllowedSourceIdsFlag(); + if (SdkLevel.isAtLeastU()) { + // This is a hack to update the flag value via mainline update. Reasons why we can't do + // this via: + // remote flag update - these are generally avoided and considered risky + // XML config - it would break GTS tests for OEMs that have a separate config copy + // default flag value - it would also require a remote flag update + sources.addAll(sAllowedNotificationSourcesUPlus); + } + + return sources; + } + + private static ArraySet<String> getNotificationsAllowedSourceIdsFlag() { return getCommaSeparatedStrings(PROPERTY_NOTIFICATIONS_ALLOWED_SOURCES); } diff --git a/service/java/com/android/safetycenter/SafetyCenterListeners.java b/service/java/com/android/safetycenter/SafetyCenterListeners.java index 5f89f46ff..091daa0a6 100644 --- a/service/java/com/android/safetycenter/SafetyCenterListeners.java +++ b/service/java/com/android/safetycenter/SafetyCenterListeners.java @@ -87,7 +87,7 @@ final class SafetyCenterListeners { */ void deliverDataForUserProfileGroup(UserProfileGroup userProfileGroup) { ArrayMap<String, SafetyCenterData> safetyCenterDataCache = new ArrayMap<>(); - int[] relevantUserIds = userProfileGroup.getProfileParentAndManagedRunningProfilesUserIds(); + int[] relevantUserIds = userProfileGroup.getAllRunningProfilesUserIds(); for (int i = 0; i < relevantUserIds.length; i++) { deliverUpdateForUser( relevantUserIds[i], @@ -105,7 +105,7 @@ final class SafetyCenterListeners { void deliverErrorForUserProfileGroup( UserProfileGroup userProfileGroup, SafetyCenterErrorDetails safetyCenterErrorDetails) { ArrayMap<String, SafetyCenterData> safetyCenterDataCache = new ArrayMap<>(); - int[] relevantUserIds = userProfileGroup.getProfileParentAndManagedRunningProfilesUserIds(); + int[] relevantUserIds = userProfileGroup.getAllRunningProfilesUserIds(); for (int i = 0; i < relevantUserIds.length; i++) { deliverUpdateForUser( relevantUserIds[i], diff --git a/service/java/com/android/safetycenter/SafetyCenterRefreshTracker.java b/service/java/com/android/safetycenter/SafetyCenterRefreshTracker.java index d98127300..cc23b4e02 100644 --- a/service/java/com/android/safetycenter/SafetyCenterRefreshTracker.java +++ b/service/java/com/android/safetycenter/SafetyCenterRefreshTracker.java @@ -34,7 +34,6 @@ import android.util.Log; import androidx.annotation.Nullable; -import com.android.permission.util.UserUtils; import com.android.safetycenter.logging.SafetyCenterStatsdLogger; import java.io.PrintWriter; @@ -175,7 +174,7 @@ public final class SafetyCenterRefreshTracker { SafetyCenterStatsdLogger.writeSourceRefreshSystemEvent( requestType, safetySourceKey.getSourceId(), - UserUtils.isManagedProfile(safetySourceKey.getUserId(), mContext), + UserProfileGroup.getProfileTypeOfUser(safetySourceKey.getUserId(), mContext), duration, sourceResult, refreshReason, @@ -284,7 +283,7 @@ public final class SafetyCenterRefreshTracker { SafetyCenterStatsdLogger.writeSourceRefreshSystemEvent( requestType, sourceKey.getSourceId(), - UserUtils.isManagedProfile(sourceKey.getUserId(), mContext), + UserProfileGroup.getProfileTypeOfUser(sourceKey.getUserId(), mContext), duration, SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__TIMEOUT, refreshReason, diff --git a/service/java/com/android/safetycenter/SafetyCenterService.java b/service/java/com/android/safetycenter/SafetyCenterService.java index 62d0a0d78..c9a5e1c03 100644 --- a/service/java/com/android/safetycenter/SafetyCenterService.java +++ b/service/java/com/android/safetycenter/SafetyCenterService.java @@ -74,6 +74,7 @@ import androidx.annotation.RequiresApi; import com.android.internal.annotations.GuardedBy; import com.android.modules.utils.BackgroundThread; import com.android.modules.utils.build.SdkLevel; +import com.android.permission.flags.Flags; import com.android.permission.util.ForegroundThread; import com.android.permission.util.UserUtils; import com.android.safetycenter.data.SafetyCenterDataManager; @@ -1076,10 +1077,21 @@ public final class SafetyCenterService extends SystemService { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_SWITCHED); filter.addAction(Intent.ACTION_USER_REMOVED); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + if (SdkLevel.isAtLeastV() && Flags.privateProfileSupported()) { + // These intents are available on V+ only, and are called for managed and other + // profile(s). + filter.addAction(Intent.ACTION_PROFILE_ADDED); + filter.addAction(Intent.ACTION_PROFILE_REMOVED); + filter.addAction(Intent.ACTION_PROFILE_AVAILABLE); + filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE); + } else { + // Only these intents are available in T and U, but that's okay because only managed + // profiles are supported by Safety Center on these SDK versions. + filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + } context.registerReceiverForAllUsers( /* receiver= */ this, filter, @@ -1108,50 +1120,86 @@ public final class SafetyCenterService extends SystemService { int userId = userHandle.getIdentifier(); Log.d(TAG, "Received action: " + action + ", for user id: " + userId); - if (!UserProfileGroup.isSupported(userId, context)) { - Log.i( - TAG, - "Received broadcast for user id: " - + userId - + ", which is an unsupported user"); + + if (!isUserIdValidForAction(action, userId, context)) { return; } - switch (action) { - case Intent.ACTION_USER_REMOVED: - case Intent.ACTION_MANAGED_PROFILE_REMOVED: - removeUserAndData(userId); - break; - case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE: - removeUser(userId); - break; - case Intent.ACTION_USER_SWITCHED: - if (userId != ActivityManager.getCurrentUser()) { - Log.w( - TAG, - "Received broadcast for user id: " - + userId - + ", which is not the current user"); - return; - } - // Fall through - case Intent.ACTION_MANAGED_PROFILE_ADDED: - case Intent.ACTION_MANAGED_PROFILE_AVAILABLE: - if (!UserUtils.isUserExistent(userId, getContext())) { - Log.w( - TAG, - "Received broadcast for user id: " - + userId - + ", which does not exist"); - return; - } - synchronized (mApiLock) { - startRefreshingSafetySourcesLocked(REFRESH_REASON_OTHER, userId); - mNotificationChannels.createAllChannelsForUser(getContext(), userHandle); - } - break; + if (isUserOrProfileRemoved(action)) { + removeUserAndData(userId); + return; + } + + if (isProfileUnavailable(action)) { + removeUser(userId); + return; + } + + if (Intent.ACTION_USER_SWITCHED.equals(action) || isProfileAddedOrAvailable(action)) { + synchronized (mApiLock) { + startRefreshingSafetySourcesLocked(REFRESH_REASON_OTHER, userId); + mNotificationChannels.createAllChannelsForUser(getContext(), userHandle); + } + return; } + Log.w(TAG, "Received unexpected broadcast with action: " + action); + } + } + + private static boolean isUserIdValidForAction( + String action, @UserIdInt int userId, Context context) { + if (!UserProfileGroup.isSupported(userId, context)) { + Log.i( + TAG, + "Received broadcast for user id: " + + userId + + ", which is an unsupported user"); + return false; + } + if (Intent.ACTION_USER_SWITCHED.equals(action) + && userId != ActivityManager.getCurrentUser()) { + Log.w( + TAG, + "Received broadcast for user id: " + + userId + + ", which is not the current user"); + return false; + } + if (isProfileAddedOrAvailable(action) && !UserUtils.isUserExistent(userId, context)) { + Log.w( + TAG, + "Received broadcast for user id: " + + userId + + ", which does not exist"); + return false; + } + return true; + } + + private static boolean isUserOrProfileRemoved(String action) { + if (Intent.ACTION_USER_REMOVED.equals(action)) { + return true; + } + if (SdkLevel.isAtLeastV() && Flags.privateProfileSupported()) { + return Intent.ACTION_PROFILE_REMOVED.equals(action); + } + return Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action); + } + + private static boolean isProfileUnavailable(String action) { + if (SdkLevel.isAtLeastV() && Flags.privateProfileSupported()) { + return Intent.ACTION_PROFILE_UNAVAILABLE.equals(action); + } + return Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action); + } + + private static boolean isProfileAddedOrAvailable(String action) { + if (SdkLevel.isAtLeastV() && Flags.privateProfileSupported()) { + return Intent.ACTION_PROFILE_AVAILABLE.equals(action) + || Intent.ACTION_PROFILE_ADDED.equals(action); } + return Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action) + || Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action); } private void removeUserAndData(@UserIdInt int userId) { diff --git a/service/java/com/android/safetycenter/SafetySources.java b/service/java/com/android/safetycenter/SafetySources.java index 02d83d27b..7be0ef00e 100644 --- a/service/java/com/android/safetycenter/SafetySources.java +++ b/service/java/com/android/safetycenter/SafetySources.java @@ -20,6 +20,8 @@ import android.safetycenter.SafetySourceData; import android.safetycenter.config.SafetySource; import android.util.Log; +import com.android.safetycenter.UserProfileGroup.ProfileType; + /** * A helper class to facilitate working with {@link SafetySource} objects. * @@ -48,6 +50,23 @@ public final class SafetySources { /** Returns whether a {@link SafetySource} supports managed profiles. */ public static boolean supportsManagedProfiles(SafetySource safetySource) { + return supportsAllProfiles(safetySource); + } + + /** + * Returns whether a {@link SafetySource} supports the profile of the given type + * {@code profileType}. + */ + public static boolean supportsProfileType( + SafetySource safetySource, @ProfileType int profileType) { + if (UserProfileGroup.PROFILE_TYPE_PRIMARY == profileType) { + return true; + } + return supportsAllProfiles(safetySource); + } + + /** Returns whether a {@link SafetySource} supports all profiles. */ + private static boolean supportsAllProfiles(SafetySource safetySource) { int safetySourceProfile = safetySource.getProfile(); switch (safetySourceProfile) { case SafetySource.PROFILE_PRIMARY: diff --git a/service/java/com/android/safetycenter/UserProfileGroup.java b/service/java/com/android/safetycenter/UserProfileGroup.java index 74b9b136f..46a440bf7 100644 --- a/service/java/com/android/safetycenter/UserProfileGroup.java +++ b/service/java/com/android/safetycenter/UserProfileGroup.java @@ -18,6 +18,7 @@ package com.android.safetycenter; import static java.util.Objects.requireNonNull; +import android.annotation.IntDef; import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageManager; @@ -31,6 +32,8 @@ import androidx.annotation.Nullable; import com.android.permission.util.UserUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -42,21 +45,47 @@ import java.util.Objects; * * @hide */ +//TODO(b/286539356) Do not expose the private profile when it's not running. public final class UserProfileGroup { private static final String TAG = "UserProfileGroup"; + // UserHandle#USER_NULL is a @TestApi so it cannot be accessed from the mainline module. + public static final @UserIdInt int USER_NULL = -10000; @UserIdInt private final int mProfileParentUserId; private final int[] mManagedProfilesUserIds; private final int[] mManagedRunningProfilesUserIds; + @UserIdInt private final int mPrivateProfileUserId; + private final boolean mPrivateProfileRunning; + + /** Respresents the profile type of the primary user. */ + public static final int PROFILE_TYPE_PRIMARY = 0; + /** Respresents the profile type of the managed profile. */ + public static final int PROFILE_TYPE_MANAGED = 1; + /** Respresents the profile type of the private profile. */ + public static final int PROFILE_TYPE_PRIVATE = 2; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = {PROFILE_TYPE_PRIMARY, PROFILE_TYPE_MANAGED, PROFILE_TYPE_PRIVATE}) + public @interface ProfileType { + // This array needs to cover all profile types. So whenever a new entry is added above then + // please remember to include it in this array as well. + int[] ALL_PROFILE_TYPES = + {PROFILE_TYPE_PRIMARY, PROFILE_TYPE_MANAGED, PROFILE_TYPE_PRIVATE}; + } + private UserProfileGroup( @UserIdInt int profileParentUserId, int[] managedProfilesUserIds, - int[] managedRunningProfilesUserIds) { + int[] managedRunningProfilesUserIds, + @UserIdInt int privateProfileUserId, + boolean privateProfileRunning) { mProfileParentUserId = profileParentUserId; mManagedProfilesUserIds = managedProfilesUserIds; mManagedRunningProfilesUserIds = managedRunningProfilesUserIds; + mPrivateProfileUserId = privateProfileUserId; + mPrivateProfileRunning = privateProfileRunning; } /** Returns all the alive {@link UserProfileGroup}s. */ @@ -117,6 +146,10 @@ public final class UserProfileGroup { int[] managedRunningProfilesUserIds = new int[userProfiles.size()]; int managedProfilesUserIdsLen = 0; int managedRunningProfilesUserIdsLen = 0; + + int privateProfileUserId = USER_NULL; + boolean privateProfileRunning = false; + for (int i = 0; i < userProfiles.size(); i++) { UserHandle userProfileHandle = userProfiles.get(i); int userProfileId = userProfileHandle.getIdentifier(); @@ -127,15 +160,19 @@ public final class UserProfileGroup { managedRunningProfilesUserIds[managedRunningProfilesUserIdsLen++] = userProfileId; } + } else if (UserUtils.isPrivateProfile(userProfileId, context)) { + privateProfileUserId = userProfileId; + privateProfileRunning = UserUtils.isProfileRunning(userProfileId, context); } } - UserProfileGroup userProfileGroup = - new UserProfileGroup( - profileParentUserId, - Arrays.copyOf(managedProfilesUserIds, managedProfilesUserIdsLen), - Arrays.copyOf( - managedRunningProfilesUserIds, managedRunningProfilesUserIdsLen)); + UserProfileGroup userProfileGroup = new UserProfileGroup( + profileParentUserId, + Arrays.copyOf(managedProfilesUserIds, managedProfilesUserIdsLen), + Arrays.copyOf(managedRunningProfilesUserIds, managedRunningProfilesUserIdsLen), + privateProfileUserId, + privateProfileRunning + ); if (!userProfileGroup.contains(userId)) { Log.i( TAG, @@ -150,7 +187,8 @@ public final class UserProfileGroup { if (!isProfile(userId, context)) { return true; } - return UserUtils.isManagedProfile(userId, context); + return UserUtils.isManagedProfile(userId, context) + || UserUtils.isPrivateProfile(userId, context); } private static UserManager getUserManagerForUser(@UserIdInt int userId, Context context) { @@ -208,32 +246,141 @@ public final class UserProfileGroup { return mProfileParentUserId; } - /** Returns the managed profile user ids of the {@link UserProfileGroup}. */ - public int[] getManagedProfilesUserIds() { - return mManagedProfilesUserIds; - } + /** + * A convenience method to get all the profile ids of all the users of all profile types. So, in + * essence, this is equivalent to iterating through all the profile types using + * {@link ProfileType#ALL_PROFILE_TYPES} and getting all the users for each of the profile type + * using {@link #getProfilesOfType(int profileType)} + */ + public int[] getAllProfilesUserIds() { + int[] allProfileIds = new int[getNumProfiles()]; + allProfileIds[0] = mProfileParentUserId; + System.arraycopy( + mManagedProfilesUserIds, + /* srcPos= */ 0, + allProfileIds, + /* destPos= */ 1, + mManagedProfilesUserIds.length); - /** Returns the running managed profile user ids of the {@link UserProfileGroup}. */ - public int[] getManagedRunningProfilesUserIds() { - return mManagedRunningProfilesUserIds; + if (mPrivateProfileUserId != USER_NULL) { + allProfileIds[allProfileIds.length - 1] = mPrivateProfileUserId; + } + + return allProfileIds; } /** - * Convenience method that combines the results of {@link - * UserProfileGroup#getProfileParentUserId()} and {@link - * UserProfileGroup#getManagedRunningProfilesUserIds()}. + * A convenience method to get all the profile ids of all the users (that are currently running) + * of all profile types. So, in essence, this is equivalent to iterating through all the profile + * {types using {@link ProfileType#ALL_PROFILE_TYPES} and getting all the users for each of the + * profile type using {@link #getProfilesOfType(int profileType)} only if they are running. */ - public int[] getProfileParentAndManagedRunningProfilesUserIds() { - int[] profileParentAndManagedRunningProfilesUserIds = - new int[mManagedRunningProfilesUserIds.length + 1]; - profileParentAndManagedRunningProfilesUserIds[0] = mProfileParentUserId; + public int[] getAllRunningProfilesUserIds() { + int[] allRunningProfileIds = new int[getNumRunningProfiles()]; + allRunningProfileIds[0] = mProfileParentUserId; System.arraycopy( mManagedRunningProfilesUserIds, /* srcPos= */ 0, - profileParentAndManagedRunningProfilesUserIds, + allRunningProfileIds, /* destPos= */ 1, mManagedRunningProfilesUserIds.length); - return profileParentAndManagedRunningProfilesUserIds; + + if (mPrivateProfileRunning) { + allRunningProfileIds[allRunningProfileIds.length - 1] = mPrivateProfileUserId; + } + + return allRunningProfileIds; + } + + /** + * Returns the profiles of the specified type. Returns an empty array if no profile of the + * specified type exists. + */ + public int[] getProfilesOfType(@ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return new int[] {mProfileParentUserId}; + case PROFILE_TYPE_MANAGED: + return mManagedProfilesUserIds; + case PROFILE_TYPE_PRIVATE: + return mPrivateProfileUserId != USER_NULL + ? new int[]{mPrivateProfileUserId} : new int[]{}; + default: + Log.w(TAG, "profiles requested for unexpected profile type " + profileType); + return new int[] {}; + } + } + + /** + * Returns the running profiles of the specified type. Returns an empty array if no profile of + * the specified type exists. + */ + public int[] getRunningProfilesOfType(@ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return new int[] {mProfileParentUserId}; + case PROFILE_TYPE_MANAGED: + return mManagedRunningProfilesUserIds; + case PROFILE_TYPE_PRIVATE: + //TODO(b/286539356) add the new feature flag protection when available. + return mPrivateProfileRunning + ? new int[] {mPrivateProfileUserId} : new int[] {}; + default: + Log.w(TAG, "Unexpected profile type " + profileType); + return new int[] {}; + } + } + + /** Returns the total number of running profiles in this user profile group */ + public int getNumRunningProfiles() { + return 1 + + mManagedRunningProfilesUserIds.length + + (mPrivateProfileRunning ? 1 : 0); + } + + /** Returns the total number of profiles in this user profile group */ + private int getNumProfiles() { + return 1 + + mManagedProfilesUserIds.length + + (mPrivateProfileUserId == USER_NULL ? 0 : 1); + } + + /** + * Returns the {@link ProfileType} for the provided {@code userId}. Note that the provided + * {@code userId} must be supported by the {@link UserProfileGroup} i.e. + * {@link #isSupported(int, Context)} should return true for {@code userId}. + */ + public static @ProfileType int getProfileTypeOfUser(@UserIdInt int userId, Context context) { + if (UserUtils.isManagedProfile(userId, context)) { + return PROFILE_TYPE_MANAGED; + } + if (UserUtils.isPrivateProfile(userId, context)) { + return PROFILE_TYPE_PRIVATE; + } + return PROFILE_TYPE_PRIMARY; + } + + /** + * Returns true iff the given userId is contained in this {@link UserProfileGroup} and it's + * running. + */ + boolean containsRunningUserId(@UserIdInt int userId, @ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return true; + case PROFILE_TYPE_MANAGED: + for (int i = 0; i < mManagedRunningProfilesUserIds.length; i++) { + if (mManagedRunningProfilesUserIds[i] == userId) { + return true; + } + } + return false; + case PROFILE_TYPE_PRIVATE: + return mPrivateProfileRunning; + default: + Log.w(TAG, "Unexpected profile type " + profileType); + return false; + } } /** Returns whether the {@link UserProfileGroup} contains the given {@code userId}. */ @@ -248,17 +395,7 @@ public final class UserProfileGroup { } } - return false; - } - - /** Returns whether the given {@code userId} is associated with a running managed profile. */ - boolean isManagedUserRunning(@UserIdInt int userId) { - for (int i = 0; i < mManagedRunningProfilesUserIds.length; i++) { - if (userId == mManagedRunningProfilesUserIds[i]) { - return true; - } - } - return false; + return USER_NULL != mPrivateProfileUserId && userId == mPrivateProfileUserId; } @Override @@ -269,7 +406,9 @@ public final class UserProfileGroup { return mProfileParentUserId == that.mProfileParentUserId && Arrays.equals(mManagedProfilesUserIds, that.mManagedProfilesUserIds) && Arrays.equals( - mManagedRunningProfilesUserIds, that.mManagedRunningProfilesUserIds); + mManagedRunningProfilesUserIds, that.mManagedRunningProfilesUserIds) + && mPrivateProfileUserId == that.mPrivateProfileUserId + && mPrivateProfileRunning == that.mPrivateProfileRunning; } @Override @@ -277,7 +416,9 @@ public final class UserProfileGroup { return Objects.hash( mProfileParentUserId, Arrays.hashCode(mManagedProfilesUserIds), - Arrays.hashCode(mManagedRunningProfilesUserIds)); + Arrays.hashCode(mManagedRunningProfilesUserIds), + mPrivateProfileUserId, + mPrivateProfileRunning); } @Override @@ -289,6 +430,10 @@ public final class UserProfileGroup { + Arrays.toString(mManagedProfilesUserIds) + ", mManagedRunningProfilesUserIds=" + Arrays.toString(mManagedRunningProfilesUserIds) + + ", mPrivateProfileUserId" + + mPrivateProfileUserId + + ", mPrivateProfileRunning" + + mPrivateProfileRunning + '}'; } } diff --git a/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java b/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java index dff7c4339..7385a2c3b 100644 --- a/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java +++ b/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java @@ -41,6 +41,7 @@ import com.android.safetycenter.SafetyCenterRefreshTracker; import com.android.safetycenter.SafetySourceIssueInfo; import com.android.safetycenter.SafetySourceKey; import com.android.safetycenter.UserProfileGroup; +import com.android.safetycenter.UserProfileGroup.ProfileType; import com.android.safetycenter.internaldata.SafetyCenterIssueActionId; import com.android.safetycenter.internaldata.SafetyCenterIssueKey; import com.android.safetycenter.logging.SafetyCenterStatsdLogger; @@ -567,7 +568,7 @@ public final class SafetyCenterDataManager { * Writes a SafetySourceStateCollected atom for the given source in response to a stats pull. */ public void logSafetySourceStateCollectedAutomatic( - SafetySourceKey sourceKey, boolean isManagedProfile) { - mSafetySourceStateCollectedLogger.writeAutomaticAtom(sourceKey, isManagedProfile); + SafetySourceKey sourceKey, @ProfileType int profileType) { + mSafetySourceStateCollectedLogger.writeAutomaticAtom(sourceKey, profileType); } } diff --git a/service/java/com/android/safetycenter/data/SafetyCenterInFlightIssueActionRepository.java b/service/java/com/android/safetycenter/data/SafetyCenterInFlightIssueActionRepository.java index 82eb3a6c7..39809aa6f 100644 --- a/service/java/com/android/safetycenter/data/SafetyCenterInFlightIssueActionRepository.java +++ b/service/java/com/android/safetycenter/data/SafetyCenterInFlightIssueActionRepository.java @@ -28,8 +28,8 @@ import android.util.Log; import androidx.annotation.Nullable; -import com.android.permission.util.UserUtils; import com.android.safetycenter.SafetySourceIssues; +import com.android.safetycenter.UserProfileGroup; import com.android.safetycenter.internaldata.SafetyCenterIssueActionId; import com.android.safetycenter.internaldata.SafetyCenterIssueKey; import com.android.safetycenter.logging.SafetyCenterStatsdLogger; @@ -87,7 +87,7 @@ final class SafetyCenterInFlightIssueActionRepository { SafetyCenterStatsdLogger.writeInlineActionSystemEvent( issueKey.getSafetySourceId(), - UserUtils.isManagedProfile(issueKey.getUserId(), mContext), + UserProfileGroup.getProfileTypeOfUser(issueKey.getUserId(), mContext), issueTypeId, duration, result); diff --git a/service/java/com/android/safetycenter/data/SafetyCenterIssueRepository.java b/service/java/com/android/safetycenter/data/SafetyCenterIssueRepository.java index 2e6f707a3..3806584a8 100644 --- a/service/java/com/android/safetycenter/data/SafetyCenterIssueRepository.java +++ b/service/java/com/android/safetycenter/data/SafetyCenterIssueRepository.java @@ -31,12 +31,12 @@ import android.safetycenter.config.SafetySourcesGroup; import android.util.SparseArray; import com.android.modules.utils.build.SdkLevel; -import com.android.permission.util.UserUtils; import com.android.safetycenter.SafetyCenterConfigReader; import com.android.safetycenter.SafetySourceIssueInfo; import com.android.safetycenter.SafetySourceKey; import com.android.safetycenter.SafetySources; import com.android.safetycenter.UserProfileGroup; +import com.android.safetycenter.UserProfileGroup.ProfileType; import com.android.safetycenter.internaldata.SafetyCenterIssueKey; import java.io.PrintWriter; @@ -88,12 +88,12 @@ final class SafetyCenterIssueRepository { * that can affect issues. */ void updateIssues(@UserIdInt int userId) { - updateIssues(userId, UserUtils.isManagedProfile(userId, mContext)); + updateIssues(userId, UserProfileGroup.getProfileTypeOfUser(userId, mContext)); } - private void updateIssues(@UserIdInt int userId, boolean isManagedProfile) { + private void updateIssues(@UserIdInt int userId, @ProfileType int profileType) { List<SafetySourceIssueInfo> issues = - getAllStoredIssuesFromRawSourceData(userId, isManagedProfile); + getAllStoredIssuesFromRawSourceData(userId, profileType); issues.sort(SAFETY_SOURCE_ISSUES_INFO_BY_SEVERITY_DESCENDING); @@ -183,14 +183,14 @@ final class SafetyCenterIssueRepository { } private List<SafetySourceIssueInfo> getAllStoredIssuesFromRawSourceData( - @UserIdInt int userId, boolean isManagedProfile) { + @UserIdInt int userId, @ProfileType int profileType) { List<SafetySourceIssueInfo> allIssuesInfo = new ArrayList<>(); List<SafetySourcesGroup> safetySourcesGroups = mSafetyCenterConfigReader.getSafetySourcesGroups(); for (int j = 0; j < safetySourcesGroups.size(); j++) { addSafetySourceIssuesInfo( - allIssuesInfo, safetySourcesGroups.get(j), userId, isManagedProfile); + allIssuesInfo, safetySourcesGroups.get(j), userId, profileType); } return allIssuesInfo; @@ -200,7 +200,7 @@ final class SafetyCenterIssueRepository { List<SafetySourceIssueInfo> issuesInfo, SafetySourcesGroup safetySourcesGroup, @UserIdInt int userId, - boolean isManagedProfile) { + @ProfileType int profileType) { List<SafetySource> safetySources = safetySourcesGroup.getSafetySources(); for (int i = 0; i < safetySources.size(); i++) { SafetySource safetySource = safetySources.get(i); @@ -208,7 +208,7 @@ final class SafetyCenterIssueRepository { if (!SafetySources.isExternal(safetySource)) { continue; } - if (isManagedProfile && !SafetySources.supportsManagedProfiles(safetySource)) { + if (!SafetySources.supportsProfileType(safetySource, profileType)) { continue; } @@ -244,12 +244,11 @@ final class SafetyCenterIssueRepository { * UserProfileGroup}. */ private List<SafetySourceIssueInfo> getIssuesFor(UserProfileGroup userProfileGroup) { - List<SafetySourceIssueInfo> issues = - new ArrayList<>(getIssuesForUser(userProfileGroup.getProfileParentUserId())); + List<SafetySourceIssueInfo> issues = new ArrayList<>(); - int[] managedRunningProfileUserIds = userProfileGroup.getManagedRunningProfilesUserIds(); - for (int i = 0; i < managedRunningProfileUserIds.length; i++) { - issues.addAll(getIssuesForUser(managedRunningProfileUserIds[i])); + int[] allRunningProfileUserIds = userProfileGroup.getAllRunningProfilesUserIds(); + for (int i = 0; i < allRunningProfileUserIds.length; i++) { + issues.addAll(getIssuesForUser(allRunningProfileUserIds[i])); } return issues; diff --git a/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java b/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java index 7355035b0..4b74b0440 100644 --- a/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java +++ b/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java @@ -29,10 +29,10 @@ import android.util.Log; import androidx.annotation.Nullable; import com.android.modules.utils.build.SdkLevel; -import com.android.permission.util.UserUtils; import com.android.safetycenter.SafetyCenterConfigReader; import com.android.safetycenter.SafetyCenterFlags; import com.android.safetycenter.SafetySources; +import com.android.safetycenter.UserProfileGroup; import java.util.List; import java.util.Set; @@ -90,10 +90,14 @@ final class SafetySourceDataValidator { validateCallingPackage(safetySource, packageName, safetySourceId); } - if (UserUtils.isManagedProfile(userId, mContext) - && !SafetySources.supportsManagedProfiles(safetySource)) { + @UserProfileGroup.ProfileType int profileType = + UserProfileGroup.getProfileTypeOfUser(userId, mContext); + if (!SafetySources.supportsProfileType(safetySource, profileType)) { throw new IllegalArgumentException( - "Unexpected managed profile request for safety source: " + safetySourceId); + "Unexpected profile type: " + + profileType + + " for safety source: " + + safetySourceId); } boolean retrievingOrClearingData = safetySourceData == null; @@ -111,6 +115,8 @@ final class SafetySourceDataValidator { } if (safetySource.getType() == SafetySource.SAFETY_SOURCE_TYPE_DYNAMIC + && safetySource.getInitialDisplayState() + != SafetySource.INITIAL_DISPLAY_STATE_HIDDEN && safetySourceStatus == null) { throw new IllegalArgumentException( "Missing status for dynamic safety source: " + safetySourceId); diff --git a/service/java/com/android/safetycenter/data/SafetySourceStateCollectedLogger.java b/service/java/com/android/safetycenter/data/SafetySourceStateCollectedLogger.java index e73459598..1bf8685bf 100644 --- a/service/java/com/android/safetycenter/data/SafetySourceStateCollectedLogger.java +++ b/service/java/com/android/safetycenter/data/SafetySourceStateCollectedLogger.java @@ -26,9 +26,10 @@ import android.safetycenter.SafetySourceStatus; import androidx.annotation.Nullable; -import com.android.permission.util.UserUtils; import com.android.safetycenter.SafetySourceIssueInfo; import com.android.safetycenter.SafetySourceKey; +import com.android.safetycenter.UserProfileGroup; +import com.android.safetycenter.UserProfileGroup.ProfileType; import com.android.safetycenter.internaldata.SafetyCenterIssueKey; import com.android.safetycenter.logging.SafetyCenterStatsdLogger; @@ -63,13 +64,13 @@ final class SafetySourceStateCollectedLogger { /** * Writes a SafetySourceStateCollected atom for the given source in response to a stats pull. */ - void writeAutomaticAtom(SafetySourceKey sourceKey, boolean isManagedProfile) { + void writeAutomaticAtom(SafetySourceKey sourceKey, @ProfileType int profileType) { logSafetySourceStateCollected( sourceKey, mSourceDataRepository.getSafetySourceData(sourceKey), /* refreshReason= */ null, /* sourceDataDiffers= */ false, - isManagedProfile, + profileType, /* safetyEvent= */ null, mSourceDataRepository.getSafetySourceLastUpdated(sourceKey)); } @@ -90,7 +91,7 @@ final class SafetySourceStateCollectedLogger { safetySourceData, refreshReason, sourceDataDiffers, - UserUtils.isManagedProfile(userId, mContext), + UserProfileGroup.getProfileTypeOfUser(userId, mContext), safetyEvent, /* lastUpdatedElapsedTimeMillis= */ null); } @@ -100,7 +101,7 @@ final class SafetySourceStateCollectedLogger { @Nullable SafetySourceData sourceData, @Nullable @SafetyCenterManager.RefreshReason Integer refreshReason, boolean sourceDataDiffers, - boolean isManagedProfile, + @ProfileType int profileType, @Nullable SafetyEvent safetyEvent, @Nullable @ElapsedRealtimeLong Long lastUpdatedElapsedTimeMillis) { SafetySourceStatus sourceStatus = sourceData == null ? null : sourceData.getStatus(); @@ -131,7 +132,7 @@ final class SafetySourceStateCollectedLogger { Integer severityLevel = maxSeverityLevel > Integer.MIN_VALUE ? maxSeverityLevel : null; SafetyCenterStatsdLogger.writeSafetySourceStateCollected( sourceKey.getSourceId(), - isManagedProfile, + profileType, severityLevel, openIssuesCount, dismissedIssuesCount, diff --git a/service/java/com/android/safetycenter/logging/SafetyCenterPullAtomCallback.java b/service/java/com/android/safetycenter/logging/SafetyCenterPullAtomCallback.java index 168d73a0f..a8dc7568e 100644 --- a/service/java/com/android/safetycenter/logging/SafetyCenterPullAtomCallback.java +++ b/service/java/com/android/safetycenter/logging/SafetyCenterPullAtomCallback.java @@ -38,6 +38,7 @@ import com.android.safetycenter.SafetyCenterFlags; import com.android.safetycenter.SafetySourceKey; import com.android.safetycenter.SafetySources; import com.android.safetycenter.UserProfileGroup; +import com.android.safetycenter.UserProfileGroup.ProfileType; import com.android.safetycenter.data.SafetyCenterDataManager; import java.util.List; @@ -149,19 +150,19 @@ public final class SafetyCenterPullAtomCallback implements StatsPullAtomCallback continue; } - writeSafetySourceStateCollectedAtomLocked( - loggableSource, - userProfileGroup.getProfileParentUserId(), - /* isUserManaged= */ false); - - if (!SafetySources.supportsManagedProfiles(loggableSource)) { - continue; - } - - int[] managedIds = userProfileGroup.getManagedRunningProfilesUserIds(); - for (int k = 0; k < managedIds.length; k++) { - writeSafetySourceStateCollectedAtomLocked( - loggableSource, managedIds[k], /* isUserManaged= */ true); + for (int profileTypeIdx = 0; + profileTypeIdx < ProfileType.ALL_PROFILE_TYPES.length; + ++profileTypeIdx) { + @ProfileType int profileType = ProfileType.ALL_PROFILE_TYPES[profileTypeIdx]; + if (!SafetySources.supportsProfileType(loggableSource, profileType)) { + continue; + } + + int[] profileIds = userProfileGroup.getProfilesOfType(profileType); + for (int profileIdx = 0; profileIdx < profileIds.length; profileIdx++) { + writeSafetySourceStateCollectedAtomLocked( + loggableSource, profileIds[profileIdx], profileType); + } } } } @@ -169,8 +170,8 @@ public final class SafetyCenterPullAtomCallback implements StatsPullAtomCallback @GuardedBy("mApiLock") private void writeSafetySourceStateCollectedAtomLocked( - SafetySource safetySource, @UserIdInt int userId, boolean isUserManaged) { + SafetySource safetySource, @UserIdInt int userId, @ProfileType int profileType) { SafetySourceKey sourceKey = SafetySourceKey.of(safetySource.getId(), userId); - mDataManager.logSafetySourceStateCollectedAutomatic(sourceKey, isUserManaged); + mDataManager.logSafetySourceStateCollectedAutomatic(sourceKey, profileType); } } diff --git a/service/java/com/android/safetycenter/logging/SafetyCenterStatsdLogger.java b/service/java/com/android/safetycenter/logging/SafetyCenterStatsdLogger.java index 710c3f7ac..3311d0c1f 100644 --- a/service/java/com/android/safetycenter/logging/SafetyCenterStatsdLogger.java +++ b/service/java/com/android/safetycenter/logging/SafetyCenterStatsdLogger.java @@ -25,6 +25,8 @@ import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTIO import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__NAVIGATION_SOURCE__SOURCE_UNKNOWN; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; +import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PRIVATE; +import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SENSOR__SENSOR_UNKNOWN; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_OK; @@ -43,12 +45,15 @@ import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVE import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__TIMEOUT; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; +import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PRIVATE; import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__COLLECTION_TYPE__AUTOMATIC; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__COLLECTION_TYPE__SOURCE_UPDATED; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; +import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PRIVATE; +import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_OK; @@ -69,6 +74,9 @@ import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SE import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_OK; import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_RECOMMENDATION; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_MANAGED; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_PRIMARY; +import static com.android.safetycenter.UserProfileGroup.PROFILE_TYPE_PRIVATE; import android.annotation.ElapsedRealtimeLong; import android.annotation.IntDef; @@ -84,6 +92,7 @@ import androidx.annotation.Nullable; import com.android.permission.PermissionStatsLog; import com.android.safetycenter.SafetyCenterFlags; +import com.android.safetycenter.UserProfileGroup.ProfileType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -161,7 +170,7 @@ public final class SafetyCenterStatsdLogger { /** Writes a {@link PermissionStatsLog#SAFETY_SOURCE_STATE_COLLECTED} atom. */ public static void writeSafetySourceStateCollected( String sourceId, - boolean isManagedProfile, + @ProfileType int profileType, @Nullable @SafetySourceData.SeverityLevel Integer sourceSeverityLevel, long openIssuesCount, long dismissedIssuesCount, @@ -181,7 +190,7 @@ public final class SafetyCenterStatsdLogger { PermissionStatsLog.write( SAFETY_SOURCE_STATE_COLLECTED, idStringToLong(sourceId), - toSourceStateCollectedProfileType(isManagedProfile), + toSourceStateCollectedProfileType(profileType), toSafetySourceStateCollectedSeverityLevel(sourceSeverityLevel), openIssuesCount, dismissedIssuesCount, @@ -203,7 +212,7 @@ public final class SafetyCenterStatsdLogger { public static void writeSourceRefreshSystemEvent( @RefreshRequestType int refreshType, String sourceId, - boolean isManagedProfile, + @ProfileType int profileType, Duration duration, @SystemEventResult int result, long refreshReason, @@ -215,7 +224,7 @@ public final class SafetyCenterStatsdLogger { SAFETY_CENTER_SYSTEM_EVENT_REPORTED, toSourceRefreshEventType(refreshType), idStringToLong(sourceId), - toSystemEventProfileType(isManagedProfile), + toSystemEventProfileType(profileType), UNSET_ISSUE_TYPE_ID, duration.toMillis(), result, @@ -254,7 +263,7 @@ public final class SafetyCenterStatsdLogger { */ public static void writeInlineActionSystemEvent( String sourceId, - boolean isManagedProfile, + @ProfileType int profileType, @Nullable String issueTypeId, Duration duration, @SystemEventResult int result) { @@ -265,7 +274,7 @@ public final class SafetyCenterStatsdLogger { SAFETY_CENTER_SYSTEM_EVENT_REPORTED, SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__INLINE_ACTION, idStringToLong(sourceId), - toSystemEventProfileType(isManagedProfile), + toSystemEventProfileType(profileType), issueTypeId == null ? UNSET_ISSUE_TYPE_ID : idStringToLong(issueTypeId), duration.toMillis(), result, @@ -279,13 +288,13 @@ public final class SafetyCenterStatsdLogger { */ public static void writeNotificationPostedEvent( String sourceId, - boolean isManagedProfile, + @ProfileType int profileType, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel) { writeNotificationInteractionReportedEvent( SAFETY_CENTER_INTERACTION_REPORTED__ACTION__NOTIFICATION_POSTED, sourceId, - isManagedProfile, + profileType, issueTypeId, sourceSeverityLevel); } @@ -296,13 +305,13 @@ public final class SafetyCenterStatsdLogger { */ public static void writeNotificationDismissedEvent( String sourceId, - boolean isManagedProfile, + @ProfileType int profileType, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel) { writeNotificationInteractionReportedEvent( SAFETY_CENTER_INTERACTION_REPORTED__ACTION__NOTIFICATION_DISMISSED, sourceId, - isManagedProfile, + profileType, issueTypeId, sourceSeverityLevel); } @@ -313,7 +322,7 @@ public final class SafetyCenterStatsdLogger { */ public static void writeNotificationActionClickedEvent( String sourceId, - boolean isManagedProfile, + @ProfileType int profileType, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel, boolean isPrimaryAction) { @@ -322,13 +331,13 @@ public final class SafetyCenterStatsdLogger { ? SAFETY_CENTER_INTERACTION_REPORTED__ACTION__ISSUE_PRIMARY_ACTION_CLICKED : SAFETY_CENTER_INTERACTION_REPORTED__ACTION__ISSUE_SECONDARY_ACTION_CLICKED; writeNotificationInteractionReportedEvent( - action, sourceId, isManagedProfile, issueTypeId, sourceSeverityLevel); + action, sourceId, profileType, issueTypeId, sourceSeverityLevel); } private static void writeNotificationInteractionReportedEvent( int interactionReportedAction, String sourceId, - boolean isManagedProfile, + @ProfileType int profileType, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel) { if (!SafetyCenterFlags.getAllowStatsdLogging()) { @@ -342,7 +351,7 @@ public final class SafetyCenterStatsdLogger { SAFETY_CENTER_INTERACTION_REPORTED__NAVIGATION_SOURCE__SOURCE_UNKNOWN, toInteractionReportedSeverityLevel(sourceSeverityLevel), idStringToLong(sourceId), - toInteractionReportedProfileType(isManagedProfile), + toInteractionReportedProfileType(profileType), idStringToLong(issueTypeId), SAFETY_CENTER_INTERACTION_REPORTED__SENSOR__SENSOR_UNKNOWN, UNSET_SOURCE_GROUP_ID, @@ -382,22 +391,43 @@ public final class SafetyCenterStatsdLogger { return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_UNKNOWN; } - private static int toSourceStateCollectedProfileType(boolean isManagedProfile) { - return isManagedProfile - ? SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED - : SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; + private static int toSourceStateCollectedProfileType(@ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; + case PROFILE_TYPE_MANAGED: + return SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; + case PROFILE_TYPE_PRIVATE: + return SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PRIVATE; + } + Log.w(TAG, "state collect arg requested for unknown profile type " + profileType); + return SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN; } - private static int toSystemEventProfileType(boolean isManagedProfile) { - return isManagedProfile - ? SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED - : SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; + private static int toSystemEventProfileType(@ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; + case PROFILE_TYPE_MANAGED: + return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; + case PROFILE_TYPE_PRIVATE: + return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PRIVATE; + } + Log.w(TAG, "system event arg requested for unknown profile type " + profileType); + return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN; } - private static int toInteractionReportedProfileType(boolean isManagedProfile) { - return isManagedProfile - ? SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED - : SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; + private static int toInteractionReportedProfileType(@ProfileType int profileType) { + switch (profileType) { + case PROFILE_TYPE_PRIMARY: + return SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; + case PROFILE_TYPE_MANAGED: + return SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; + case PROFILE_TYPE_PRIVATE: + return SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PRIVATE; + } + Log.w(TAG, "interaction enum requested for unknown profile type " + profileType); + return SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN; } /** diff --git a/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationReceiver.java b/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationReceiver.java index ed0e95177..6cfa39580 100644 --- a/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationReceiver.java +++ b/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationReceiver.java @@ -27,7 +27,6 @@ import android.util.Log; import androidx.annotation.Nullable; import com.android.internal.annotations.GuardedBy; -import com.android.permission.util.UserUtils; import com.android.safetycenter.ApiLock; import com.android.safetycenter.PendingIntentFactory; import com.android.safetycenter.SafetyCenterDataChangeNotifier; @@ -214,7 +213,7 @@ public final class SafetyCenterNotificationReceiver extends BroadcastReceiver { if (dismissedIssue != null) { SafetyCenterStatsdLogger.writeNotificationDismissedEvent( issueKey.getSafetySourceId(), - UserUtils.isManagedProfile(userId, context), + UserProfileGroup.getProfileTypeOfUser(userId, context), dismissedIssue.getIssueTypeId(), dismissedIssue.getSeverityLevel()); } @@ -240,7 +239,7 @@ public final class SafetyCenterNotificationReceiver extends BroadcastReceiver { if (issue != null) { SafetyCenterStatsdLogger.writeNotificationActionClickedEvent( issueKey.getSafetySourceId(), - UserUtils.isManagedProfile(issueKey.getUserId(), context), + UserProfileGroup.getProfileTypeOfUser(issueKey.getUserId(), context), issue.getIssueTypeId(), issue.getSeverityLevel(), SafetySourceIssues.isPrimaryAction( diff --git a/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationSender.java b/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationSender.java index d17090c34..2e298fa90 100644 --- a/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationSender.java +++ b/service/java/com/android/safetycenter/notifications/SafetyCenterNotificationSender.java @@ -37,7 +37,6 @@ import android.util.Log; import androidx.annotation.Nullable; import com.android.modules.utils.build.SdkLevel; -import com.android.permission.util.UserUtils; import com.android.safetycenter.SafetyCenterFlags; import com.android.safetycenter.SafetySourceIssueInfo; import com.android.safetycenter.SafetySourceIssues; @@ -210,11 +209,9 @@ public final class SafetyCenterNotificationSender { /** Updates Safety Center notifications for the given {@link UserProfileGroup}. */ public void updateNotifications(UserProfileGroup userProfileGroup) { - updateNotifications(userProfileGroup.getProfileParentUserId()); - - int[] managedProfileUserIds = userProfileGroup.getManagedProfilesUserIds(); - for (int i = 0; i < managedProfileUserIds.length; i++) { - updateNotifications(managedProfileUserIds[i]); + int[] allProfilesUserIds = userProfileGroup.getAllProfilesUserIds(); + for (int i = 0; i < allProfilesUserIds.length; i++) { + updateNotifications(allProfilesUserIds[i]); } } @@ -387,7 +384,7 @@ public final class SafetyCenterNotificationSender { mNotifiedIssues.put(key, issue); SafetyCenterStatsdLogger.writeNotificationPostedEvent( key.getSafetySourceId(), - UserUtils.isManagedProfile(key.getUserId(), mContext), + UserProfileGroup.getProfileTypeOfUser(key.getUserId(), mContext), issue.getIssueTypeId(), issue.getSeverityLevel()); } diff --git a/service/lint-baseline.xml b/service/lint-baseline.xml index dd7e79ef5..226175e91 100644 --- a/service/lint-baseline.xml +++ b/service/lint-baseline.xml @@ -1,42 +1,48 @@ <?xml version="1.0" encoding="UTF-8"?> -<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev"> +<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01"> <issue id="NewApi" - message="Call requires API level 31 (current min is 30): `android.os.UserHandle#getUid`" - errorLine1=" return UserHandle.of(userId).getUid(appId);" - errorLine2=" ~~~~~~"> + message="Call requires API level 34 (current min is 33): `getDeduplicationGroup`" + errorLine1=" String deduplicationGroup = issueInfo.getSafetySource().getDeduplicationGroup();" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/service/java/com/android/permission/compat/UserHandleCompat.java" - line="57" - column="38"/> + file="packages/modules/Permission/service/java/com/android/safetycenter/data/SafetyCenterIssueDeduplicator.java" + line="316" + column="65"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 33): `android.content.pm.PackageManager#getPackageUidAsUser`" - errorLine1=" packageManager.getPackageUidAsUser(" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> + message="Call requires API level 34 (current min is 33): `getDeduplicationId`" + errorLine1=" String deduplicationId = issueInfo.getSafetySourceIssue().getDeduplicationId();" + errorLine2=" ~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/service/java/com/android/safetycenter/SafetyCenterService.java" - line="651" - column="40"/> + file="packages/modules/Permission/service/java/com/android/safetycenter/data/SafetyCenterIssueDeduplicator.java" + line="317" + column="67"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 33): `getDeduplicationGroup`"> + message="Call requires API level 34 (current min is 33): `android.content.pm.PackageManager#getPackageUidAsUser`" + errorLine1=" packageManager.getPackageUidAsUser(" + errorLine2=" ~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/Permission/service/java/com/android/safetycenter/data/SafetyCenterIssueDeduplicator.java" - line="315"/> + file="packages/modules/Permission/service/java/com/android/safetycenter/SafetyCenterService.java" + line="732" + column="40"/> </issue> <issue id="NewApi" - message="Call requires API level 34 (current min is 33): `getDeduplicationId`"> + message="Call requires API level 31 (current min is 30): `android.os.UserHandle#getUid`" + errorLine1=" return UserHandle.of(userId).getUid(appId);" + errorLine2=" ~~~~~~"> <location - file="packages/modules/Permission/service/java/com/android/safetycenter/data/SafetyCenterIssueDeduplicator.java" - line="316"/> + file="packages/modules/Permission/service/java/com/android/permission/compat/UserHandleCompat.java" + line="57" + column="38"/> </issue> </issues>
\ No newline at end of file diff --git a/tests/cts/permission/Android.bp b/tests/cts/permission/Android.bp index 8849f41a7..ed7fcea25 100644 --- a/tests/cts/permission/Android.bp +++ b/tests/cts/permission/Android.bp @@ -30,6 +30,7 @@ android_test { "general-tests", "sts", "mts-permission", + "mcts-permission", ], // Include both the 32 and 64 bit versions compile_multilib: "both", @@ -52,6 +53,8 @@ android_test { "sts-device-util", "platform-test-rules", "CtsVirtualDeviceCommonLib", + "android.permission.flags-aconfig-java", + "androidx.test.rules", ], jni_libs: [ "libctspermission_jni", diff --git a/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/Android.bp b/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/Android.bp index fdb0be452..df6bdf5c3 100644 --- a/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/Android.bp +++ b/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/Android.bp @@ -31,5 +31,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/AndroidManifest.xml b/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/AndroidManifest.xml index ef4d82dfc..ece3ba1c7 100644 --- a/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/AndroidManifest.xml +++ b/tests/cts/permission/AppThatAccessesCalendarContactsBodySensorCustomPermission/AndroidManifest.xml @@ -34,6 +34,7 @@ <uses-permission android:name="android.permission.WRITE_CALENDAR" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.BODY_SENSORS" /> + <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.cts.appthatrequestcustompermission.TEST_PERMISSION" /> <application /> diff --git a/tests/cts/permission/AppThatAccessesLocationOnCommand/Android.bp b/tests/cts/permission/AppThatAccessesLocationOnCommand/Android.bp index 2bb3dd3ab..d4573d264 100644 --- a/tests/cts/permission/AppThatAccessesLocationOnCommand/Android.bp +++ b/tests/cts/permission/AppThatAccessesLocationOnCommand/Android.bp @@ -32,6 +32,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], srcs: [ "src/**/*.java", diff --git a/tests/cts/permission/AppThatAlsoDefinesPermissionA/Android.bp b/tests/cts/permission/AppThatAlsoDefinesPermissionA/Android.bp index 46b7aecd3..af002df2b 100644 --- a/tests/cts/permission/AppThatAlsoDefinesPermissionA/Android.bp +++ b/tests/cts/permission/AppThatAlsoDefinesPermissionA/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatAlsoDefinesPermissionADifferentCert/Android.bp b/tests/cts/permission/AppThatAlsoDefinesPermissionADifferentCert/Android.bp index c88d0f7fe..6a622ca46 100644 --- a/tests/cts/permission/AppThatAlsoDefinesPermissionADifferentCert/Android.bp +++ b/tests/cts/permission/AppThatAlsoDefinesPermissionADifferentCert/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert/Android.bp b/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert/Android.bp index b1ef695ac..98f0a9aeb 100644 --- a/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert/Android.bp +++ b/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert30/Android.bp b/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert30/Android.bp index 52900dfc3..dd46066e9 100644 --- a/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert30/Android.bp +++ b/tests/cts/permission/AppThatAlsoDefinesPermissionGroupADifferentCert30/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatDefinesPermissionA/Android.bp b/tests/cts/permission/AppThatDefinesPermissionA/Android.bp index 54a575b4f..e8125cd76 100644 --- a/tests/cts/permission/AppThatDefinesPermissionA/Android.bp +++ b/tests/cts/permission/AppThatDefinesPermissionA/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup/Android.bp b/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup/Android.bp index 9029b3a98..06f181f40 100644 --- a/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup/Android.bp +++ b/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup30/Android.bp b/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup30/Android.bp index 04961e265..527594589 100644 --- a/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup30/Android.bp +++ b/tests/cts/permission/AppThatDefinesPermissionWithInvalidGroup30/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatDefinesPermissionWithPlatformGroup/Android.bp b/tests/cts/permission/AppThatDefinesPermissionWithPlatformGroup/Android.bp index 687ad7488..8d6279704 100644 --- a/tests/cts/permission/AppThatDefinesPermissionWithPlatformGroup/Android.bp +++ b/tests/cts/permission/AppThatDefinesPermissionWithPlatformGroup/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatDefinesUndefinedPermissionGroupElement/Android.bp b/tests/cts/permission/AppThatDefinesUndefinedPermissionGroupElement/Android.bp index c00d26d3a..684fd0559 100644 --- a/tests/cts/permission/AppThatDefinesUndefinedPermissionGroupElement/Android.bp +++ b/tests/cts/permission/AppThatDefinesUndefinedPermissionGroupElement/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], srcs: ["src/**/*.kt"], } diff --git a/tests/cts/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp b/tests/cts/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp index f9ff21c6f..6e9936996 100644 --- a/tests/cts/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp +++ b/tests/cts/permission/AppThatDoesNotHaveBgLocationAccess/Android.bp @@ -32,5 +32,6 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatHasNotificationListener/Android.bp b/tests/cts/permission/AppThatHasNotificationListener/Android.bp index 419ab5d66..3f3563e87 100644 --- a/tests/cts/permission/AppThatHasNotificationListener/Android.bp +++ b/tests/cts/permission/AppThatHasNotificationListener/Android.bp @@ -32,6 +32,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], srcs: [ "src/**/*.java", diff --git a/tests/cts/permission/AppThatRequestBluetoothPermission30/Android.bp b/tests/cts/permission/AppThatRequestBluetoothPermission30/Android.bp index a3fe38109..5909e12b0 100644 --- a/tests/cts/permission/AppThatRequestBluetoothPermission30/Android.bp +++ b/tests/cts/permission/AppThatRequestBluetoothPermission30/Android.bp @@ -35,6 +35,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], srcs: [":AppThatRequestBluetoothPermission"], } diff --git a/tests/cts/permission/AppThatRequestBluetoothPermission31/Android.bp b/tests/cts/permission/AppThatRequestBluetoothPermission31/Android.bp index 7dc2e2445..c5abe6c18 100644 --- a/tests/cts/permission/AppThatRequestBluetoothPermission31/Android.bp +++ b/tests/cts/permission/AppThatRequestBluetoothPermission31/Android.bp @@ -28,6 +28,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], srcs: [":AppThatRequestBluetoothPermission"], } diff --git a/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocation31/Android.bp b/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocation31/Android.bp index 857f2e2f4..f5a0faa3a 100644 --- a/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocation31/Android.bp +++ b/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocation31/Android.bp @@ -28,6 +28,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], srcs: [":AppThatRequestBluetoothPermission"], } diff --git a/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocationNoProvider/Android.bp b/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocationNoProvider/Android.bp index 6f635c0cc..88a2765ca 100644 --- a/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocationNoProvider/Android.bp +++ b/tests/cts/permission/AppThatRequestBluetoothPermissionNeverForLocationNoProvider/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestContactsAndCallLogPermission16/Android.bp b/tests/cts/permission/AppThatRequestContactsAndCallLogPermission16/Android.bp index 1a057d010..a1364df32 100644 --- a/tests/cts/permission/AppThatRequestContactsAndCallLogPermission16/Android.bp +++ b/tests/cts/permission/AppThatRequestContactsAndCallLogPermission16/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestContactsPermission15/Android.bp b/tests/cts/permission/AppThatRequestContactsPermission15/Android.bp index 54618447e..bb9ea42dc 100644 --- a/tests/cts/permission/AppThatRequestContactsPermission15/Android.bp +++ b/tests/cts/permission/AppThatRequestContactsPermission15/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestContactsPermission16/Android.bp b/tests/cts/permission/AppThatRequestContactsPermission16/Android.bp index 2dca5aa2c..a378c0c7f 100644 --- a/tests/cts/permission/AppThatRequestContactsPermission16/Android.bp +++ b/tests/cts/permission/AppThatRequestContactsPermission16/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestDevicePermissions/Android.bp b/tests/cts/permission/AppThatRequestDevicePermissions/Android.bp index c0a9f9914..10ee18ed6 100644 --- a/tests/cts/permission/AppThatRequestDevicePermissions/Android.bp +++ b/tests/cts/permission/AppThatRequestDevicePermissions/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission28/Android.bp b/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission28/Android.bp index 5a60a3fbd..eaf10f50c 100644 --- a/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission28/Android.bp +++ b/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission28/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "vts10", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission29/Android.bp b/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission29/Android.bp index de6c3cbb2..095c24093 100644 --- a/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission29/Android.bp +++ b/tests/cts/permission/AppThatRequestLocationAndBackgroundPermission29/Android.bp @@ -29,5 +29,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestLocationPermission22/Android.bp b/tests/cts/permission/AppThatRequestLocationPermission22/Android.bp index 25d9893ec..32d8505fb 100644 --- a/tests/cts/permission/AppThatRequestLocationPermission22/Android.bp +++ b/tests/cts/permission/AppThatRequestLocationPermission22/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestLocationPermission28/Android.bp b/tests/cts/permission/AppThatRequestLocationPermission28/Android.bp index bfeadbd58..29ade84d2 100644 --- a/tests/cts/permission/AppThatRequestLocationPermission28/Android.bp +++ b/tests/cts/permission/AppThatRequestLocationPermission28/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestLocationPermission29/Android.bp b/tests/cts/permission/AppThatRequestLocationPermission29/Android.bp index ee3982ea4..240795b30 100644 --- a/tests/cts/permission/AppThatRequestLocationPermission29/Android.bp +++ b/tests/cts/permission/AppThatRequestLocationPermission29/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestLocationPermission29v4/Android.bp b/tests/cts/permission/AppThatRequestLocationPermission29v4/Android.bp index b56bb25eb..262438a04 100644 --- a/tests/cts/permission/AppThatRequestLocationPermission29v4/Android.bp +++ b/tests/cts/permission/AppThatRequestLocationPermission29v4/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestMultiplePermissionsWithMinMaxSdk/Android.bp b/tests/cts/permission/AppThatRequestMultiplePermissionsWithMinMaxSdk/Android.bp index 5fcc6c8ba..4a8cddd5c 100644 --- a/tests/cts/permission/AppThatRequestMultiplePermissionsWithMinMaxSdk/Android.bp +++ b/tests/cts/permission/AppThatRequestMultiplePermissionsWithMinMaxSdk/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestOneTimePermission/Android.bp b/tests/cts/permission/AppThatRequestOneTimePermission/Android.bp index c12a70871..50a347928 100644 --- a/tests/cts/permission/AppThatRequestOneTimePermission/Android.bp +++ b/tests/cts/permission/AppThatRequestOneTimePermission/Android.bp @@ -30,6 +30,7 @@ android_test_helper_app { "cts", "mts-permission", "general-tests", + "mcts-permission", ], srcs: ["src/**/*.java"], } diff --git a/tests/cts/permission/AppThatRequestPermissionAandB/Android.bp b/tests/cts/permission/AppThatRequestPermissionAandB/Android.bp index 6c037b456..b583b4603 100644 --- a/tests/cts/permission/AppThatRequestPermissionAandB/Android.bp +++ b/tests/cts/permission/AppThatRequestPermissionAandB/Android.bp @@ -28,6 +28,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], srcs: ["src/**/*.java"], } diff --git a/tests/cts/permission/AppThatRequestPermissionAandC/Android.bp b/tests/cts/permission/AppThatRequestPermissionAandC/Android.bp index b94965334..ae309b0bb 100644 --- a/tests/cts/permission/AppThatRequestPermissionAandC/Android.bp +++ b/tests/cts/permission/AppThatRequestPermissionAandC/Android.bp @@ -28,6 +28,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], srcs: ["src/**/*.java"], } diff --git a/tests/cts/permission/AppThatRequestStoragePermission28/Android.bp b/tests/cts/permission/AppThatRequestStoragePermission28/Android.bp index 50ae9209b..a2bd97b3c 100644 --- a/tests/cts/permission/AppThatRequestStoragePermission28/Android.bp +++ b/tests/cts/permission/AppThatRequestStoragePermission28/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestStoragePermission29/Android.bp b/tests/cts/permission/AppThatRequestStoragePermission29/Android.bp index 4663be9dc..5b1c73f3a 100644 --- a/tests/cts/permission/AppThatRequestStoragePermission29/Android.bp +++ b/tests/cts/permission/AppThatRequestStoragePermission29/Android.bp @@ -27,5 +27,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestSystemAlertWindow22/Android.bp b/tests/cts/permission/AppThatRequestSystemAlertWindow22/Android.bp index 43cc9de97..8f0ff524f 100644 --- a/tests/cts/permission/AppThatRequestSystemAlertWindow22/Android.bp +++ b/tests/cts/permission/AppThatRequestSystemAlertWindow22/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRequestSystemAlertWindow23/Android.bp b/tests/cts/permission/AppThatRequestSystemAlertWindow23/Android.bp index 403257d45..73c5c8813 100644 --- a/tests/cts/permission/AppThatRequestSystemAlertWindow23/Android.bp +++ b/tests/cts/permission/AppThatRequestSystemAlertWindow23/Android.bp @@ -28,5 +28,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppThatRunsRationaleTests/Android.bp b/tests/cts/permission/AppThatRunsRationaleTests/Android.bp index 30019fba5..f6826784c 100644 --- a/tests/cts/permission/AppThatRunsRationaleTests/Android.bp +++ b/tests/cts/permission/AppThatRunsRationaleTests/Android.bp @@ -29,6 +29,7 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], srcs: ["src/**/*.java"], diff --git a/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission28/Android.bp b/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission28/Android.bp index 8214c425d..43e40d887 100644 --- a/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission28/Android.bp +++ b/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission28/Android.bp @@ -29,5 +29,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission29/Android.bp b/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission29/Android.bp index 3df5c9a7d..c76088043 100644 --- a/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission29/Android.bp +++ b/tests/cts/permission/AppWithSharedUidThatRequestLocationPermission29/Android.bp @@ -29,5 +29,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppWithSharedUidThatRequestsNoPermissions/Android.bp b/tests/cts/permission/AppWithSharedUidThatRequestsNoPermissions/Android.bp index 7dd3ef638..a00cf0df1 100644 --- a/tests/cts/permission/AppWithSharedUidThatRequestsNoPermissions/Android.bp +++ b/tests/cts/permission/AppWithSharedUidThatRequestsNoPermissions/Android.bp @@ -26,5 +26,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/AppWithSharedUidThatRequestsPermissions/Android.bp b/tests/cts/permission/AppWithSharedUidThatRequestsPermissions/Android.bp index c58b3e81e..ff95c1b86 100644 --- a/tests/cts/permission/AppWithSharedUidThatRequestsPermissions/Android.bp +++ b/tests/cts/permission/AppWithSharedUidThatRequestsPermissions/Android.bp @@ -26,5 +26,6 @@ android_test_helper_app { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/StorageEscalationApp28/Android.bp b/tests/cts/permission/StorageEscalationApp28/Android.bp index 9ea70f565..f0c86433b 100644 --- a/tests/cts/permission/StorageEscalationApp28/Android.bp +++ b/tests/cts/permission/StorageEscalationApp28/Android.bp @@ -26,5 +26,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/StorageEscalationApp29Full/Android.bp b/tests/cts/permission/StorageEscalationApp29Full/Android.bp index dcb64e68a..810032059 100644 --- a/tests/cts/permission/StorageEscalationApp29Full/Android.bp +++ b/tests/cts/permission/StorageEscalationApp29Full/Android.bp @@ -26,5 +26,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/StorageEscalationApp29Scoped/Android.bp b/tests/cts/permission/StorageEscalationApp29Scoped/Android.bp index 8a780c07b..12a5310e2 100644 --- a/tests/cts/permission/StorageEscalationApp29Scoped/Android.bp +++ b/tests/cts/permission/StorageEscalationApp29Scoped/Android.bp @@ -26,5 +26,6 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], } diff --git a/tests/cts/permission/sdk28/Android.bp b/tests/cts/permission/sdk28/Android.bp index 3043c9329..2bdffabe5 100644 --- a/tests/cts/permission/sdk28/Android.bp +++ b/tests/cts/permission/sdk28/Android.bp @@ -29,5 +29,6 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt b/tests/cts/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt index e7bad2b05..227fbfb9a 100644 --- a/tests/cts/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt +++ b/tests/cts/permission/src/android/permission/cts/AccessibilityPrivacySourceTest.kt @@ -24,7 +24,6 @@ import android.app.UiAutomation import android.content.ComponentName import android.content.Context import android.os.Build -import android.os.Process import android.permission.cts.CtsNotificationListenerServiceUtils.assertEmptyNotification import android.permission.cts.CtsNotificationListenerServiceUtils.assertNotificationExist import android.permission.cts.CtsNotificationListenerServiceUtils.cancelNotification @@ -92,15 +91,6 @@ class AccessibilityPrivacySourceTest { ) @get:Rule - val deviceConfigA11ySourceEnabled = - DeviceConfigStateChangerRule( - context, - DeviceConfig.NAMESPACE_PRIVACY, - ACCESSIBILITY_SOURCE_ENABLED, - true.toString() - ) - - @get:Rule val deviceConfigA11yListenerDisabled = DeviceConfigStateChangerRule( context, @@ -115,11 +105,6 @@ class AccessibilityPrivacySourceTest { InstrumentedAccessibilityService.disableAllServices() runShellCommand("input keyevent KEYCODE_WAKEUP") resetPermissionController() - // Bypass battery saving restrictions - runShellCommand( - "cmd tare set-vip " + - "${Process.myUserHandle().identifier} $permissionControllerPackage true" - ) cancelNotifications(permissionControllerPackage) assertEmptyNotification(permissionControllerPackage, ACCESSIBILITY_NOTIFICATION_ID) runWithShellPermissionIdentity { safetyCenterManager?.clearAllSafetySourceDataForTests() } @@ -133,11 +118,6 @@ class AccessibilityPrivacySourceTest { @After fun cleanup() { cancelNotifications(permissionControllerPackage) - // Reset battery saving restrictions - runShellCommand( - "cmd tare set-vip " + - "${Process.myUserHandle().identifier} $permissionControllerPackage default" - ) runWithShellPermissionIdentity { safetyCenterManager?.clearAllSafetySourceDataForTests() } } @@ -233,26 +213,6 @@ class AccessibilityPrivacySourceTest { } @Test - fun testJobWithAccessibilityFeatureDisabledDoesNotSendNotification() { - setDeviceConfigPrivacyProperty(ACCESSIBILITY_SOURCE_ENABLED, false.toString()) - mAccessibilityServiceRule.enableService() - runJobAndWaitUntilCompleted() - assertEmptyNotification(permissionControllerPackage, ACCESSIBILITY_NOTIFICATION_ID) - } - - @Test - fun testJobWithAccessibilityFeatureDisabledDoesNotSendIssueToSafetyCenter() { - setDeviceConfigPrivacyProperty(ACCESSIBILITY_SOURCE_ENABLED, false.toString()) - mAccessibilityServiceRule.enableService() - runJobAndWaitUntilCompleted() - assertSafetyCenterIssueDoesNotExist( - SC_ACCESSIBILITY_SOURCE_ID, - safetyCenterIssueId, - SC_ACCESSIBILITY_ISSUE_TYPE_ID - ) - } - - @Test fun testJobWithSafetyCenterDisabledDoesNotSendNotification() { setDeviceConfigPrivacyProperty(SAFETY_CENTER_ENABLED, false.toString()) mAccessibilityServiceRule.enableService() @@ -332,7 +292,6 @@ class AccessibilityPrivacySourceTest { companion object { private const val SC_ACCESSIBILITY_SOURCE_ID = "AndroidAccessibility" - private const val ACCESSIBILITY_SOURCE_ENABLED = "sc_accessibility_source_enabled" private const val SAFETY_CENTER_ENABLED = "safety_center_is_enabled" private const val ACCESSIBILITY_LISTENER_ENABLED = "sc_accessibility_listener_enabled" private const val ACCESSIBILITY_JOB_INTERVAL_MILLIS = "sc_accessibility_job_interval_millis" diff --git a/tests/cts/permission/src/android/permission/cts/AppWidgetManagerPermissionTest.java b/tests/cts/permission/src/android/permission/cts/AppWidgetManagerPermissionTest.java index 294896d97..fa43bfb18 100644 --- a/tests/cts/permission/src/android/permission/cts/AppWidgetManagerPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/AppWidgetManagerPermissionTest.java @@ -20,7 +20,8 @@ import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.pm.PackageManager; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Test that protected AppWidgetManager APIs cannot be called without permissions diff --git a/tests/cts/permission/src/android/permission/cts/BaseNotificationListenerCheckTest.java b/tests/cts/permission/src/android/permission/cts/BaseNotificationListenerCheckTest.java index 42da8c830..a4551f610 100644 --- a/tests/cts/permission/src/android/permission/cts/BaseNotificationListenerCheckTest.java +++ b/tests/cts/permission/src/android/permission/cts/BaseNotificationListenerCheckTest.java @@ -137,18 +137,12 @@ public class BaseNotificationListenerCheckTest { @BeforeClass public static void beforeClassSetup() throws Exception { - // Bypass battery saving restrictions - runShellCommand("cmd tare set-vip " - + myUserHandle().getIdentifier() + " " + PERMISSION_CONTROLLER_PKG + " true"); // Disallow any OEM enabled NLS disallowPreexistingNotificationListeners(); } @AfterClass public static void afterClassTearDown() throws Throwable { - // Reset battery saving restrictions - runShellCommand("cmd tare set-vip " - + myUserHandle().getIdentifier() + " " + PERMISSION_CONTROLLER_PKG + " default"); // Reallow any previously OEM allowed NLS reallowPreexistingNotificationListeners(); } diff --git a/tests/cts/permission/src/android/permission/cts/CameraPermissionTest.java b/tests/cts/permission/src/android/permission/cts/CameraPermissionTest.java index 99f2862f1..981735388 100644 --- a/tests/cts/permission/src/android/permission/cts/CameraPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/CameraPermissionTest.java @@ -19,7 +19,8 @@ package android.permission.cts; import android.hardware.Camera; import android.os.Environment; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; + +import androidx.test.filters.MediumTest; import java.io.FileOutputStream; diff --git a/tests/cts/permission/src/android/permission/cts/ContactsProviderTest.java b/tests/cts/permission/src/android/permission/cts/ContactsProviderTest.java index 984fd6cfe..69b64d790 100644 --- a/tests/cts/permission/src/android/permission/cts/ContactsProviderTest.java +++ b/tests/cts/permission/src/android/permission/cts/ContactsProviderTest.java @@ -19,7 +19,8 @@ package android.permission.cts; import android.content.ContentValues; import android.provider.ContactsContract; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify permissions are enforced. diff --git a/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt b/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt index ac02d53b5..3af2f895f 100644 --- a/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt +++ b/tests/cts/permission/src/android/permission/cts/DevicePermissionsTest.kt @@ -21,17 +21,25 @@ import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND import android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE import android.app.Instrumentation import android.companion.virtual.VirtualDeviceManager +import android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT import android.companion.virtual.VirtualDeviceManager.VirtualDevice import android.companion.virtual.VirtualDeviceParams import android.content.Context import android.content.Intent import android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME +import android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED +import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED +import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET import android.content.pm.PackageManager.PERMISSION_DENIED import android.content.pm.PackageManager.PERMISSION_GRANTED import android.os.Build import android.os.UserHandle import android.permission.PermissionManager +import android.permission.flags.Flags import android.platform.test.annotations.AppModeFull +import android.platform.test.annotations.RequiresFlagsDisabled +import android.platform.test.annotations.RequiresFlagsEnabled +import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.virtualdevice.cts.common.FakeAssociationRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SdkSuppress @@ -57,6 +65,7 @@ class DevicePermissionsTest { private lateinit var virtualDevice: VirtualDevice private lateinit var virtualDeviceContext: Context + private lateinit var persistentDeviceId: String private lateinit var permissionManager: PermissionManager @@ -69,9 +78,12 @@ class DevicePermissionsTest { Manifest.permission.CREATE_VIRTUAL_DEVICE, Manifest.permission.GRANT_RUNTIME_PERMISSIONS, Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS, - Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, + Manifest.permission.GET_RUNTIME_PERMISSIONS ) + @Rule @JvmField val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() + @Before fun setup() { val virtualDeviceManager = @@ -84,6 +96,7 @@ class DevicePermissionsTest { ) virtualDeviceContext = defaultDeviceContext.createDeviceContext(virtualDevice.deviceId) permissionManager = virtualDeviceContext.getSystemService(PermissionManager::class.java)!! + persistentDeviceId = virtualDevice.persistentDeviceId!! runShellCommandOrThrow("pm install -r $TEST_APK") } @@ -93,11 +106,16 @@ class DevicePermissionsTest { virtualDevice.close() } + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) @Test fun testDeviceAwareRuntimePermissionIsGranted() { grantPermissionAndAssertGranted(Manifest.permission.CAMERA, virtualDeviceContext) } + @RequiresFlagsDisabled(Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED) @Test fun testDeviceAwareRuntimePermissionGrantIsInherited() { grantPermissionAndAssertGranted(Manifest.permission.CAMERA, defaultDeviceContext) @@ -107,33 +125,29 @@ class DevicePermissionsTest { @Test fun testNonDeviceAwareRuntimePermissionGrantIsInherited() { - grantPermissionAndAssertGranted(Manifest.permission.READ_CONTACTS, defaultDeviceContext) + grantPermissionAndAssertGranted(NON_DEVICE_AWARE_PERMISSION, defaultDeviceContext) - assertPermission( - Manifest.permission.READ_CONTACTS, - PERMISSION_GRANTED, - virtualDeviceContext - ) + assertPermission(NON_DEVICE_AWARE_PERMISSION, PERMISSION_GRANTED, virtualDeviceContext) } + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) @Test fun testDeviceAwareRuntimePermissionIsRevoked() { - grantPermissionAndAssertGranted(Manifest.permission.RECORD_AUDIO, virtualDeviceContext) + grantPermissionAndAssertGranted(DEVICE_AWARE_PERMISSION, virtualDeviceContext) - revokePermissionAndAssertDenied(Manifest.permission.RECORD_AUDIO, virtualDeviceContext) + revokePermissionAndAssertDenied(DEVICE_AWARE_PERMISSION, virtualDeviceContext) } @Test fun testNonDeviceAwareRuntimePermissionIsRevokedForDefaultDevice() { - grantPermissionAndAssertGranted(Manifest.permission.READ_CONTACTS, defaultDeviceContext) - assertPermission( - Manifest.permission.READ_CONTACTS, - PERMISSION_GRANTED, - virtualDeviceContext - ) + grantPermissionAndAssertGranted(NON_DEVICE_AWARE_PERMISSION, defaultDeviceContext) + assertPermission(NON_DEVICE_AWARE_PERMISSION, PERMISSION_GRANTED, virtualDeviceContext) // Revoke call from virtualDeviceContext should revoke for default device as well. - revokePermissionAndAssertDenied(Manifest.permission.READ_CONTACTS, virtualDeviceContext) - assertPermission(Manifest.permission.READ_CONTACTS, PERMISSION_DENIED, defaultDeviceContext) + revokePermissionAndAssertDenied(NON_DEVICE_AWARE_PERMISSION, virtualDeviceContext) + assertPermission(NON_DEVICE_AWARE_PERMISSION, PERMISSION_DENIED, defaultDeviceContext) } @Test @@ -148,9 +162,9 @@ class DevicePermissionsTest { @Test fun testOneTimePermissionIsRevoked() { - grantPermissionAndAssertGranted(Manifest.permission.RECORD_AUDIO, virtualDeviceContext) + grantPermissionAndAssertGranted(DEVICE_AWARE_PERMISSION, virtualDeviceContext) virtualDeviceContext.packageManager.updatePermissionFlags( - Manifest.permission.RECORD_AUDIO, + DEVICE_AWARE_PERMISSION, TEST_PACKAGE_NAME, FLAG_PERMISSION_ONE_TIME, FLAG_PERMISSION_ONE_TIME, @@ -165,28 +179,322 @@ class DevicePermissionsTest { IMPORTANCE_FOREGROUND_SERVICE ) eventually { - assertPermission( - Manifest.permission.RECORD_AUDIO, - PERMISSION_DENIED, - virtualDeviceContext - ) + assertPermission(DEVICE_AWARE_PERMISSION, PERMISSION_DENIED, virtualDeviceContext) } } + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) @Test fun testRevokeSelfPermissionOnKill() { - grantPermissionAndAssertGranted(Manifest.permission.RECORD_AUDIO, virtualDeviceContext) + grantPermissionAndAssertGranted(DEVICE_AWARE_PERMISSION, virtualDeviceContext) - revokeSelfPermission(Manifest.permission.RECORD_AUDIO, virtualDeviceContext) + revokeSelfPermission(DEVICE_AWARE_PERMISSION, virtualDeviceContext) eventually { - assertPermission( - Manifest.permission.RECORD_AUDIO, - PERMISSION_DENIED, - virtualDeviceContext - ) + assertPermission(DEVICE_AWARE_PERMISSION, PERMISSION_DENIED, virtualDeviceContext) } } + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun testGrantAndRevokeDeviceAwarePermissionByPersistentDeviceId() { + val deviceAwarePermission = DEVICE_AWARE_PERMISSION + + permissionManager.grantRuntimePermission( + TEST_PACKAGE_NAME, + deviceAwarePermission, + persistentDeviceId + ) + + assertThat( + permissionManager.checkPermission( + deviceAwarePermission, + TEST_PACKAGE_NAME, + virtualDevice.persistentDeviceId!! + ) + ) + .isEqualTo(PERMISSION_GRANTED) + + assertThat( + permissionManager.checkPermission( + deviceAwarePermission, + TEST_PACKAGE_NAME, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + ) + ) + .isEqualTo(PERMISSION_DENIED) + + permissionManager.revokeRuntimePermission( + TEST_PACKAGE_NAME, + deviceAwarePermission, + persistentDeviceId, + "test" + ) + + assertThat( + permissionManager.checkPermission( + deviceAwarePermission, + TEST_PACKAGE_NAME, + virtualDevice.persistentDeviceId!! + ) + ) + .isEqualTo(PERMISSION_DENIED) + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun testUpdateAndGetPermissionFlagsByPersistentDeviceId() { + val deviceAwarePermission = DEVICE_AWARE_PERMISSION + val flagMask = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_USER_FIXED + val flag = FLAG_PERMISSION_USER_SET + + assertThat( + permissionManager.getPermissionFlags( + TEST_PACKAGE_NAME, + deviceAwarePermission, + persistentDeviceId + ) + ) + .isEqualTo(0) + + permissionManager.updatePermissionFlags( + TEST_PACKAGE_NAME, + deviceAwarePermission, + persistentDeviceId, + flagMask, + flag + ) + + assertThat( + permissionManager.getPermissionFlags( + TEST_PACKAGE_NAME, + deviceAwarePermission, + persistentDeviceId + ) + ) + .isEqualTo(FLAG_PERMISSION_USER_SET) + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun testAllPermissionStatesApiGrantForVirtualDevice() { + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId) + .isEmpty() + ) + .isTrue() + + permissionManager.grantRuntimePermission( + TEST_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + persistentDeviceId + ) + + val permissionStateMap = + permissionManager.getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId) + assertThat(permissionStateMap.size).isEqualTo(1) + assertThat(permissionStateMap[DEVICE_AWARE_PERMISSION]!!.isGranted).isTrue() + assertThat(permissionStateMap[DEVICE_AWARE_PERMISSION]!!.flags).isEqualTo(0) + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, PERSISTENT_DEVICE_ID_DEFAULT) + .contains(DEVICE_AWARE_PERMISSION) + ) + .isFalse() + + permissionManager.revokeRuntimePermission( + TEST_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + persistentDeviceId, + "test" + ) + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId) + .contains(DEVICE_AWARE_PERMISSION) + ) + .isFalse() + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun testAllPermissionStatesApiFlagsForVirtualDevice() { + val flagMask = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_USER_FIXED + val flag = FLAG_PERMISSION_USER_SET + + assertThat(permissionManager.getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId)) + .isEmpty() + + permissionManager.updatePermissionFlags( + TEST_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + persistentDeviceId, + flagMask, + flag + ) + + assertThat( + hasPermission( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId)[ + DEVICE_AWARE_PERMISSION]!! + .flags, + flag + ) + ) + .isTrue() + + assertThat( + hasPermission( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId)[ + DEVICE_AWARE_PERMISSION]!! + .flags, + FLAG_PERMISSION_USER_FIXED + ) + ) + .isFalse() + } + + @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @Test + fun testAllPermissionStatesApiGrantForDefaultDevice() { + // Setting a flag explicitly so that the permission consistently stays in the state upon + // revoke + permissionManager.updatePermissionFlags( + TEST_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + PERSISTENT_DEVICE_ID_DEFAULT, + FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, + FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED + ) + + permissionManager.grantRuntimePermission( + TEST_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + PERSISTENT_DEVICE_ID_DEFAULT + ) + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, PERSISTENT_DEVICE_ID_DEFAULT)[ + DEVICE_AWARE_PERMISSION]!! + .isGranted + ) + .isTrue() + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId) + .contains(DEVICE_AWARE_PERMISSION) + ) + .isFalse() + + permissionManager.revokeRuntimePermission( + TEST_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + PERSISTENT_DEVICE_ID_DEFAULT, + "test" + ) + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, PERSISTENT_DEVICE_ID_DEFAULT)[ + DEVICE_AWARE_PERMISSION]!! + .isGranted + ) + .isFalse() + } + + @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @Test + fun testAllPermissionStatesApiFlagsForDefaultDevice() { + val flagMask = FLAG_PERMISSION_USER_SET or FLAG_PERMISSION_USER_FIXED + val flag = FLAG_PERMISSION_USER_SET + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, PERSISTENT_DEVICE_ID_DEFAULT) + .contains(DEVICE_AWARE_PERMISSION) + ) + .isFalse() + + permissionManager.updatePermissionFlags( + TEST_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + PERSISTENT_DEVICE_ID_DEFAULT, + flagMask, + flag + ) + + assertThat( + hasPermission( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, PERSISTENT_DEVICE_ID_DEFAULT)[ + DEVICE_AWARE_PERMISSION]!! + .flags, + flag + ) + ) + .isTrue() + + assertThat( + hasPermission( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, PERSISTENT_DEVICE_ID_DEFAULT)[ + DEVICE_AWARE_PERMISSION]!! + .flags, + FLAG_PERMISSION_USER_FIXED + ) + ) + .isFalse() + } + + @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @Test + fun testAllPermissionStatesApiThatNonDeviceAwareRuntimePermissionGrantIsNotInherited() { + permissionManager.grantRuntimePermission( + TEST_PACKAGE_NAME, + NON_DEVICE_AWARE_PERMISSION, + PERSISTENT_DEVICE_ID_DEFAULT + ) + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, PERSISTENT_DEVICE_ID_DEFAULT)[ + NON_DEVICE_AWARE_PERMISSION]!! + .isGranted + ) + .isTrue() + + assertThat( + permissionManager + .getAllPermissionStates(TEST_PACKAGE_NAME, persistentDeviceId) + .contains(NON_DEVICE_AWARE_PERMISSION) + ) + .isFalse() + } + + private fun hasPermission(permissionFlags: Int, permissionBit: Int): Boolean = + permissionFlags and permissionBit != 0 + private fun revokeSelfPermission(permissionName: String, context: Context) { val intent = Intent(PERMISSION_SELF_REVOKE_INTENT) intent.setClassName(TEST_PACKAGE_NAME, PERMISSION_SELF_REVOKE_RECEIVER) @@ -235,5 +543,8 @@ class DevicePermissionsTest { "android.permission.cts.appthatrequestpermission.REVOKE_SELF_PERMISSION" private const val PERMISSION_SELF_REVOKE_RECEIVER = "android.permission.cts.appthatrequestpermission.RevokeSelfPermissionReceiver" + + private const val DEVICE_AWARE_PERMISSION = Manifest.permission.RECORD_AUDIO + private const val NON_DEVICE_AWARE_PERMISSION = Manifest.permission.READ_CONTACTS } } diff --git a/tests/cts/permission/src/android/permission/cts/LocationAccessCheckTest.java b/tests/cts/permission/src/android/permission/cts/LocationAccessCheckTest.java index f59883921..2bb2ed4c7 100644 --- a/tests/cts/permission/src/android/permission/cts/LocationAccessCheckTest.java +++ b/tests/cts/permission/src/android/permission/cts/LocationAccessCheckTest.java @@ -474,7 +474,6 @@ public class LocationAccessCheckTest { wakeUpAndDismissKeyguard(); bindService(); resetPermissionControllerBeforeEachTest(); - bypassBatterySavingRestrictions(); assumeCanGetFineLocation(); } @@ -497,11 +496,6 @@ public class LocationAccessCheckTest { runShellCommand("cmd jobscheduler reset-schedule-quota"); } - public void bypassBatterySavingRestrictions() { - runShellCommand("cmd tare set-vip " + myUserHandle().getIdentifier() - + " " + PERMISSION_CONTROLLER_PKG + " true"); - } - /** * Make sure fine location can be accessed at all. */ @@ -564,7 +558,6 @@ public class LocationAccessCheckTest { public void cleanupAfterEachTest() throws Throwable { resetPrivacyConfig(); locationUnbind(); - resetBatterySavingRestrictions(); } /** @@ -579,11 +572,6 @@ public class LocationAccessCheckTest { unbindService(); } - public void resetBatterySavingRestrictions() { - runShellCommand("cmd tare set-vip " + myUserHandle().getIdentifier() - + " " + PERMISSION_CONTROLLER_PKG + " default"); - } - @Test public void notificationIsShown() throws Throwable { accessLocation(); diff --git a/tests/cts/permission/src/android/permission/cts/MinMaxSdkVersionTest.kt b/tests/cts/permission/src/android/permission/cts/MinMaxSdkVersionTest.kt index 58eaf598c..4679fbee8 100644 --- a/tests/cts/permission/src/android/permission/cts/MinMaxSdkVersionTest.kt +++ b/tests/cts/permission/src/android/permission/cts/MinMaxSdkVersionTest.kt @@ -80,7 +80,7 @@ class MinMaxSdkVersionTest { mContext!! .packageManager .getPackageInfo(TEST_APP_PKG_NAME, PackageManager.GET_PERMISSIONS) - return packageInfo.requestedPermissions.any { it == permName } + return packageInfo.requestedPermissions!!.any { it == permName } } companion object { diff --git a/tests/cts/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java index 835ba124c..3d9ba8214 100644 --- a/tests/cts/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoActivityRelatedPermissionTest.java @@ -21,7 +21,8 @@ import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.MediumTest; + +import androidx.test.filters.MediumTest; import java.util.List; diff --git a/tests/cts/permission/src/android/permission/cts/NoAudioPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoAudioPermissionTest.java index c2c42a10d..50498b1d5 100644 --- a/tests/cts/permission/src/android/permission/cts/NoAudioPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoAudioPermissionTest.java @@ -25,9 +25,10 @@ import android.media.AudioManager; import android.media.AudioRecord; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import androidx.test.filters.SmallTest; + /** * Verify the audio related operations require specific permissions. */ diff --git a/tests/cts/permission/src/android/permission/cts/NoBroadcastPackageRemovedPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoBroadcastPackageRemovedPermissionTest.java index 5630c5b8c..1a46842b2 100644 --- a/tests/cts/permission/src/android/permission/cts/NoBroadcastPackageRemovedPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoBroadcastPackageRemovedPermissionTest.java @@ -19,7 +19,8 @@ package android.permission.cts; import android.content.Intent; import android.os.Bundle; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify Context related methods without specific BROADCAST series permissions. diff --git a/tests/cts/permission/src/android/permission/cts/NoCaptureVideoPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoCaptureVideoPermissionTest.java index 6ad048308..e0573044c 100644 --- a/tests/cts/permission/src/android/permission/cts/NoCaptureVideoPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoCaptureVideoPermissionTest.java @@ -22,9 +22,10 @@ import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.ImageReader; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.util.DisplayMetrics; +import androidx.test.filters.SmallTest; + /** * Verify the capture system video output permission requirements. */ diff --git a/tests/cts/permission/src/android/permission/cts/NoKeyPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoKeyPermissionTest.java index 5a0b25993..ac77947d9 100644 --- a/tests/cts/permission/src/android/permission/cts/NoKeyPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoKeyPermissionTest.java @@ -19,7 +19,8 @@ package android.permission.cts; import android.app.KeyguardManager; import android.content.Context; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify the key input related operations require specific permissions. diff --git a/tests/cts/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java index b8d2ee21a..5dc73d520 100644 --- a/tests/cts/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java @@ -19,7 +19,8 @@ package android.permission.cts; import android.content.Context; import android.net.ConnectivityManager; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import java.net.InetAddress; diff --git a/tests/cts/permission/src/android/permission/cts/NoReadLogsPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoReadLogsPermissionTest.java index b6fb84dc7..f0d70b2ce 100644 --- a/tests/cts/permission/src/android/permission/cts/NoReadLogsPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoReadLogsPermissionTest.java @@ -21,7 +21,8 @@ import android.system.Os; import android.system.OsConstants; import android.system.StructStat; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; + +import androidx.test.filters.MediumTest; import java.io.BufferedReader; import java.io.IOException; diff --git a/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java index 51b3bd830..437aa19c4 100644 --- a/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java @@ -28,7 +28,8 @@ import android.os.VibratorManager; import android.platform.test.annotations.AppModeFull; import android.telephony.gsm.SmsManager; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import java.io.IOException; import java.io.InputStream; diff --git a/tests/cts/permission/src/android/permission/cts/NoWakeLockPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoWakeLockPermissionTest.java index 030f341aa..95c4da727 100644 --- a/tests/cts/permission/src/android/permission/cts/NoWakeLockPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoWakeLockPermissionTest.java @@ -26,7 +26,8 @@ import android.net.wifi.WifiManager.WifiLock; import android.os.PowerManager; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify the Wake Lock related operations require specific permissions. diff --git a/tests/cts/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java b/tests/cts/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java index 18e4375bc..fc1d6b59f 100644 --- a/tests/cts/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java +++ b/tests/cts/permission/src/android/permission/cts/NoWallpaperPermissionsTest.java @@ -27,7 +27,8 @@ import android.content.Context; import android.graphics.Bitmap; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import org.junit.function.ThrowingRunnable; diff --git a/tests/cts/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java b/tests/cts/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java index df3ec3c64..7ebb09f98 100644 --- a/tests/cts/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java +++ b/tests/cts/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java @@ -21,7 +21,8 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify the PackageManager related operations require specific permissions. diff --git a/tests/cts/permission/src/android/permission/cts/PermissionControllerTest.java b/tests/cts/permission/src/android/permission/cts/PermissionControllerTest.java index 05b45c9b1..4367d2bf6 100644 --- a/tests/cts/permission/src/android/permission/cts/PermissionControllerTest.java +++ b/tests/cts/permission/src/android/permission/cts/PermissionControllerTest.java @@ -423,7 +423,7 @@ public class PermissionControllerTest { } assertThat(permissionInfos).isNotEmpty(); - assertThat(runtimePermissions.size()).isEqualTo(5); + assertThat(runtimePermissions.size()).isEqualTo(6); assertRuntimePermissionLabelsAreValid(runtimePermissions, permissionInfos, 4, APP2); } diff --git a/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java b/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java index 05aa41d69..33975f91c 100644 --- a/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java +++ b/tests/cts/permission/src/android/permission/cts/PermissionUpdateListenerTest.java @@ -23,18 +23,26 @@ import static com.android.compatibility.common.util.SystemUtil.runWithShellPermi import static com.google.common.truth.Truth.assertThat; import android.companion.virtual.VirtualDeviceManager; +import android.companion.virtual.VirtualDeviceParams; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.OnPermissionsChangedListener; +import android.permission.flags.Flags; import android.platform.test.annotations.AppModeFull; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; +import android.virtualdevice.cts.common.FakeAssociationRule; import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.compatibility.common.util.AdoptShellPermissionsRule; import com.android.compatibility.common.util.SystemUtil; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -52,15 +60,28 @@ public class PermissionUpdateListenerTest { + "CtsAppThatRequestsCalendarContactsBodySensorCustomPermission.apk"; private static final String PACKAGE_NAME = "android.permission.cts.appthatrequestcustompermission"; - private static final String PERMISSION_NAME = "android.permission.READ_CONTACTS"; + private static final String PERMISSION_NAME = "android.permission.RECORD_AUDIO"; private static final int TIMEOUT = 10000; - private final Context mContext = + private final Context mDefaultContext = InstrumentationRegistry.getInstrumentation().getContext(); - private final PackageManager mPackageManager = mContext.getPackageManager(); + private final PackageManager mPackageManager = mDefaultContext.getPackageManager(); private int mTestAppUid; + private VirtualDeviceManager mVirtualDeviceManager; + + @Rule + public FakeAssociationRule mFakeAssociationRule = new FakeAssociationRule(); + + @Rule + public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule( + InstrumentationRegistry.getInstrumentation().getUiAutomation(), + android.Manifest.permission.CREATE_VIRTUAL_DEVICE); + + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + @Before public void setup() throws PackageManager.NameNotFoundException, InterruptedException { runShellCommandOrThrow("pm install " + APK); @@ -69,6 +90,7 @@ public class PermissionUpdateListenerTest { SystemUtil.waitForBroadcasts(); Thread.sleep(1000); mTestAppUid = mPackageManager.getPackageUid(PACKAGE_NAME, 0); + mVirtualDeviceManager = mDefaultContext.getSystemService(VirtualDeviceManager.class); } @After @@ -89,7 +111,7 @@ public class PermissionUpdateListenerTest { runWithShellPermissionIdentity(() -> { mPackageManager.addOnPermissionsChangeListener(permissionsChangedListener); mPackageManager.grantRuntimePermission(PACKAGE_NAME, PERMISSION_NAME, - mContext.getUser()); + mDefaultContext.getUser()); }); countDownLatch.await(TIMEOUT, TimeUnit.MILLISECONDS); runWithShellPermissionIdentity(() -> { @@ -100,61 +122,120 @@ public class PermissionUpdateListenerTest { } @Test - public void testGrantPermissionNotifyListener() throws InterruptedException { + @RequiresFlagsEnabled({Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED}) + public void testVirtualDeviceGrantPermissionNotifyListener() throws InterruptedException { + VirtualDeviceManager.VirtualDevice virtualDevice = + mVirtualDeviceManager.createVirtualDevice( + mFakeAssociationRule.getAssociationInfo().getId(), + new VirtualDeviceParams.Builder().build()); + Context deviceContext = mDefaultContext.createDeviceContext(virtualDevice.getDeviceId()); + testGrantPermissionNotifyListener(deviceContext, virtualDevice.getPersistentDeviceId()); + } + + @Test + public void testDefaultDeviceGrantPermissionNotifyListener() throws InterruptedException { + testGrantPermissionNotifyListener( + mDefaultContext, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); + } + + private void testGrantPermissionNotifyListener( + Context context, String expectedDeviceId) throws InterruptedException { + final PackageManager packageManager = context.getPackageManager(); TestOnPermissionsChangedListener permissionsChangedListener = new TestOnPermissionsChangedListener(1); runWithShellPermissionIdentity(() -> { - mPackageManager.addOnPermissionsChangeListener(permissionsChangedListener); - mPackageManager.grantRuntimePermission(PACKAGE_NAME, PERMISSION_NAME, - mContext.getUser()); + packageManager.addOnPermissionsChangeListener(permissionsChangedListener); + packageManager.grantRuntimePermission(PACKAGE_NAME, PERMISSION_NAME, + mDefaultContext.getUser()); }); permissionsChangedListener.waitForPermissionChangedCallbacks(); runWithShellPermissionIdentity(() -> { - mPackageManager.removeOnPermissionsChangeListener(permissionsChangedListener); + packageManager.removeOnPermissionsChangeListener(permissionsChangedListener); }); String deviceId = permissionsChangedListener.getNotifiedDeviceId(mTestAppUid); - assertThat(deviceId).isEqualTo(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); + assertThat(deviceId).isEqualTo(expectedDeviceId); } @Test - public void testRevokePermissionNotifyListener() throws InterruptedException { + public void testDefaultDeviceRevokePermissionNotifyListener() throws InterruptedException { + testRevokePermissionNotifyListener( + mDefaultContext, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); + } + + @Test + @RequiresFlagsEnabled({Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED}) + public void testVirtualDeviceRevokePermissionNotifyListener() throws InterruptedException { + VirtualDeviceManager.VirtualDevice virtualDevice = + mVirtualDeviceManager.createVirtualDevice( + mFakeAssociationRule.getAssociationInfo().getId(), + new VirtualDeviceParams.Builder().build()); + Context deviceContext = mDefaultContext.createDeviceContext(virtualDevice.getDeviceId()); + testRevokePermissionNotifyListener( + deviceContext, virtualDevice.getPersistentDeviceId()); + } + + private void testRevokePermissionNotifyListener( + Context context, String expectedDeviceId) throws InterruptedException { + final PackageManager packageManager = context.getPackageManager(); TestOnPermissionsChangedListener permissionsChangedListener = new TestOnPermissionsChangedListener(1); runWithShellPermissionIdentity(() -> { - mPackageManager.grantRuntimePermission(PACKAGE_NAME, PERMISSION_NAME, - mContext.getUser()); - mPackageManager.addOnPermissionsChangeListener(permissionsChangedListener); - mPackageManager.revokeRuntimePermission(PACKAGE_NAME, PERMISSION_NAME, - mContext.getUser()); + packageManager.grantRuntimePermission(PACKAGE_NAME, PERMISSION_NAME, + mDefaultContext.getUser()); + packageManager.addOnPermissionsChangeListener(permissionsChangedListener); + packageManager.revokeRuntimePermission(PACKAGE_NAME, PERMISSION_NAME, + mDefaultContext.getUser()); }); permissionsChangedListener.waitForPermissionChangedCallbacks(); runWithShellPermissionIdentity(() -> { - mPackageManager.removeOnPermissionsChangeListener(permissionsChangedListener); + packageManager.removeOnPermissionsChangeListener(permissionsChangedListener); }); String deviceId = permissionsChangedListener.getNotifiedDeviceId(mTestAppUid); - assertThat(deviceId).isEqualTo(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); + assertThat(deviceId).isEqualTo(expectedDeviceId); } @Test - public void testUpdatePermissionFlagsNotifyListener() throws InterruptedException { + public void testDefaultDeviceUpdatePermissionFlagsNotifyListener() throws InterruptedException { + testUpdatePermissionFlagsNotifyListener( + mDefaultContext, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); + } + + @Test + @RequiresFlagsEnabled({Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED}) + public void testVirtualDeviceUpdatePermissionFlagsNotifyListener() throws InterruptedException { + VirtualDeviceManager.VirtualDevice virtualDevice = + mVirtualDeviceManager.createVirtualDevice( + mFakeAssociationRule.getAssociationInfo().getId(), + new VirtualDeviceParams.Builder().build()); + Context deviceContext = mDefaultContext.createDeviceContext(virtualDevice.getDeviceId()); + testUpdatePermissionFlagsNotifyListener( + deviceContext, virtualDevice.getPersistentDeviceId()); + } + + private void testUpdatePermissionFlagsNotifyListener( + Context context, String expectedDeviceId) throws InterruptedException { TestOnPermissionsChangedListener permissionsChangedListener = new TestOnPermissionsChangedListener(1); + final PackageManager packageManager = context.getPackageManager(); runWithShellPermissionIdentity(() -> { - mPackageManager.addOnPermissionsChangeListener(permissionsChangedListener); + packageManager.addOnPermissionsChangeListener(permissionsChangedListener); int flag = PackageManager.FLAG_PERMISSION_USER_SET; - mPackageManager.updatePermissionFlags(PERMISSION_NAME, PACKAGE_NAME, flag, flag, - mContext.getUser()); + packageManager.updatePermissionFlags(PERMISSION_NAME, PACKAGE_NAME, flag, flag, + mDefaultContext.getUser()); }); permissionsChangedListener.waitForPermissionChangedCallbacks(); runWithShellPermissionIdentity(() -> { - mPackageManager.removeOnPermissionsChangeListener(permissionsChangedListener); + packageManager.removeOnPermissionsChangeListener(permissionsChangedListener); }); String deviceId = permissionsChangedListener.getNotifiedDeviceId(mTestAppUid); - assertThat(deviceId).isEqualTo(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); + assertThat(deviceId).isEqualTo(expectedDeviceId); } private class TestOnPermissionsChangedListener diff --git a/tests/cts/permission/src/android/permission/cts/ProviderPermissionTest.java b/tests/cts/permission/src/android/permission/cts/ProviderPermissionTest.java index 9f5a813d1..83c2ffaee 100644 --- a/tests/cts/permission/src/android/permission/cts/ProviderPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/ProviderPermissionTest.java @@ -35,12 +35,11 @@ import android.provider.ContactsContract; import android.provider.Settings; import android.provider.Telephony; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; import android.util.Log; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.MediumTest; -import java.util.ArrayList; import java.util.List; import java.util.Objects; diff --git a/tests/cts/permission/src/android/permission/cts/RebootPermissionTest.java b/tests/cts/permission/src/android/permission/cts/RebootPermissionTest.java index b1d3d5afb..13f17dce8 100644 --- a/tests/cts/permission/src/android/permission/cts/RebootPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/RebootPermissionTest.java @@ -18,7 +18,8 @@ package android.permission.cts; import android.content.Intent; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify that rebooting requires Permission. diff --git a/tests/cts/permission/src/android/permission/cts/RecordSensitiveContentPermissionTest.kt b/tests/cts/permission/src/android/permission/cts/RecordSensitiveContentPermissionTest.kt new file mode 100644 index 000000000..b80f89938 --- /dev/null +++ b/tests/cts/permission/src/android/permission/cts/RecordSensitiveContentPermissionTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.permission.cts + +import android.os.Build +import android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION +import android.platform.test.annotations.AppModeFull +import android.platform.test.annotations.RequiresFlagsEnabled +import android.platform.test.flag.junit.CheckFlagsRule +import android.platform.test.flag.junit.DeviceFlagsValueProvider +import androidx.test.InstrumentationRegistry +import androidx.test.filters.SdkSuppress +import org.junit.Assert +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(JUnit4::class) +@AppModeFull(reason = "Instant apps cannot install packages") +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = "VanillaIceCream") +class RecordSensitiveContentPermissionTest { + @Rule + @JvmField + val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() + + @Test + @RequiresFlagsEnabled(FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION) + fun testRecordSensitiveContentDuringProjection() { + val packageManager = InstrumentationRegistry.getContext().getPackageManager() + val packagesHoldingPermission = + packageManager + .getPackagesHoldingPermissions( + arrayOf(android.Manifest.permission.RECORD_SENSITIVE_CONTENT), + 0 + ) + .map { it.packageName } + + if (packagesHoldingPermission.size > 1) { + Assert.fail( + "Only one system app on the device is allowed to hold the " + + "RECORD_SENSITIVE_CONTENT_DURING_PROJECTION permission, " + + "packages holding the permissions are: " + + packagesHoldingPermission + ) + } + } +} diff --git a/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt b/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt index 05235e141..579b03f9c 100644 --- a/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt +++ b/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt @@ -50,21 +50,6 @@ class RevokePermissionTest { @Test @AppModeFull(reason = "Instant apps can't revoke permissions.") - fun testRevokePermissionNotRequested() { - testRevoke( - packageName = APP_PKG_NAME, - permission = CAMERA, - throwableType = SecurityException::class.java, - throwableMessages = - listOf( - "has not requested permission", - "Permission $CAMERA isn't requested by package $APP_PKG_NAME" - ) - ) - } - - @Test - @AppModeFull(reason = "Instant apps can't revoke permissions.") fun testRevokeFakePermission() { val fakePermissionName = "FAKE_PERMISSION" testRevoke( @@ -100,22 +85,6 @@ class RevokePermissionTest { @Test @AppModeFull(reason = "Instant apps can't revoke permissions.") - fun testRevokePermissionNotRequestedWithReason() { - testRevoke( - packageName = APP_PKG_NAME, - permission = CAMERA, - reason = "test reason", - throwableType = SecurityException::class.java, - throwableMessages = - listOf( - "has not requested permission", - "Permission $CAMERA isn't requested by package $APP_PKG_NAME" - ) - ) - } - - @Test - @AppModeFull(reason = "Instant apps can't revoke permissions.") fun testRevokeFakePermissionWithReason() { val fakePermissionName = "FAKE_PERMISSION" testRevoke( diff --git a/tests/cts/permission/src/android/permission/cts/RevokeSawPermissionTest.kt b/tests/cts/permission/src/android/permission/cts/RevokeSawPermissionTest.kt index 17327c6d4..57a2f7fcb 100644 --- a/tests/cts/permission/src/android/permission/cts/RevokeSawPermissionTest.kt +++ b/tests/cts/permission/src/android/permission/cts/RevokeSawPermissionTest.kt @@ -17,6 +17,7 @@ package android.permission.cts import android.content.pm.PackageManager +import android.platform.test.annotations.AppModeFull import android.platform.test.annotations.AsbSecurityTest import androidx.test.platform.app.InstrumentationRegistry import org.junit.After @@ -27,6 +28,7 @@ private val APP_PKG_NAME = "android.permission.cts.usesystemalertwindowpermissio private val APK_22 = "/data/local/tmp/cts-permission/" + "CtsAppThatRequestsSystemAlertWindow22.apk" private val APK_23 = "/data/local/tmp/cts-permission/" + "CtsAppThatRequestsSystemAlertWindow23.apk" +@AppModeFull class RevokeSawPermissionTest { fun installApp(apk: String) { diff --git a/tests/cts/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java b/tests/cts/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java index 8609e3379..0c1c885be 100644 --- a/tests/cts/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java +++ b/tests/cts/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java @@ -17,7 +17,6 @@ package android.permission.cts; import static android.content.Context.DEVICE_POLICY_SERVICE; -import static android.content.Context.FINGERPRINT_SERVICE; import static android.content.Context.SHORTCUT_SERVICE; import static android.content.Context.USB_SERVICE; import static android.content.Context.WALLPAPER_SERVICE; @@ -49,12 +48,6 @@ public class ServicesInstantAppsCannotAccessTests { } @Test - public void cannotGetFingerprintManager() { - assertNull(InstrumentationRegistry.getTargetContext().getSystemService( - FINGERPRINT_SERVICE)); - } - - @Test public void cannotGetShortcutManager() { assertNull(InstrumentationRegistry.getTargetContext().getSystemService( SHORTCUT_SERVICE)); diff --git a/tests/cts/permission/telephony/Android.bp b/tests/cts/permission/telephony/Android.bp index bbfe06c55..5ded57ab3 100644 --- a/tests/cts/permission/telephony/Android.bp +++ b/tests/cts/permission/telephony/Android.bp @@ -26,6 +26,7 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], // Include both the 32 and 64 bit versions compile_multilib: "both", diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp index 6f0bcf111..344787045 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], certificate: ":cts-testkey1", } diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp index 41f01e981..4265d0924 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], certificate: ":cts-testkey2", } diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp index a3e1f13d2..987d29039 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], certificate: ":cts-testkey1", } diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp index caaa8e898..9fcebb09b 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], certificate: ":cts-testkey1", } diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp index d9ca4c8ea..a153e39c5 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], certificate: ":cts-testkey2", } diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp index b4ea30ada..6efcfdd01 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], certificate: ":cts-testkey1", } diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp index 22c6ccd6f..ab0b8a7b5 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "mts-permission", "sts", + "mcts-permission", ], certificate: ":cts-testkey2", } diff --git a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp index 5627a3d36..41333cb57 100644 --- a/tests/cts/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp +++ b/tests/cts/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.bp @@ -27,6 +27,7 @@ android_test_helper_app { "general-tests", "sts", "mts-permission", + "mcts-permission", ], certificate: ":cts-testkey1", } diff --git a/tests/cts/permissionmultidevice/Android.bp b/tests/cts/permissionmultidevice/Android.bp index 61ac6541d..fdd115b5e 100644 --- a/tests/cts/permissionmultidevice/Android.bp +++ b/tests/cts/permissionmultidevice/Android.bp @@ -46,5 +46,6 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permissionmultidevice/AndroidManifest.xml b/tests/cts/permissionmultidevice/AndroidManifest.xml index e7c993d57..9bad85813 100644 --- a/tests/cts/permissionmultidevice/AndroidManifest.xml +++ b/tests/cts/permissionmultidevice/AndroidManifest.xml @@ -20,6 +20,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="android.permissionmultidevice.cts"> + <uses-feature android:name="android.software.companion_device_setup" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> diff --git a/tests/cts/permissionmultidevice/AndroidTest.xml b/tests/cts/permissionmultidevice/AndroidTest.xml index 2b43fd01c..d86bea2d5 100644 --- a/tests/cts/permissionmultidevice/AndroidTest.xml +++ b/tests/cts/permissionmultidevice/AndroidTest.xml @@ -37,13 +37,6 @@ <option name="disable-device-config-sync" value="true" /> </target_preparer> - <target_preparer class="com.android.tradefed.targetprep.FeatureFlagTargetPreparer"> - <option name="flag-value" - value="permissions/com.android.permission.flags.device_aware_permission_grant=true"/> - <option name="flag-value" - value="virtual_devices/android.companion.virtual.flags.stream_permissions=true"/> - </target_preparer> - <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> <option name="cleanup-apks" value="true" /> <option name="test-file-name" value="CtsPermissionMultiDeviceTestCases.apk" /> diff --git a/tests/cts/permissionmultidevice/TEST_MAPPNG b/tests/cts/permissionmultidevice/TEST_MAPPING index 80a2cf2ce..f56ee5b1c 100644 --- a/tests/cts/permissionmultidevice/TEST_MAPPNG +++ b/tests/cts/permissionmultidevice/TEST_MAPPING @@ -1,5 +1,5 @@ { - "presubmit": [ + "postsubmit": [ { "name": "CtsPermissionMultiDeviceTestCases" } diff --git a/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt b/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt index 0eff95a3d..e8d35e614 100644 --- a/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt +++ b/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt @@ -26,6 +26,7 @@ class FakeVirtualDeviceRule : FakeAssociationRule() { private lateinit var virtualDeviceManager: VirtualDeviceManager lateinit var virtualDevice: VirtualDeviceManager.VirtualDevice + lateinit var deviceDisplayName: String var virtualDisplayId: Int = -1 override fun before() { @@ -57,6 +58,10 @@ class FakeVirtualDeviceRule : FakeAssociationRule() { ) Truth.assertThat(display).isNotNull() virtualDisplayId = display!!.display.displayId + deviceDisplayName = + virtualDeviceManager + .getDisplayNameForPersistentDeviceId(virtualDevice.persistentDeviceId!!) + .toString() } } diff --git a/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/PermissionUtils.kt b/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/PermissionUtils.kt index fa58fc9f7..225e19d49 100644 --- a/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/PermissionUtils.kt +++ b/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/PermissionUtils.kt @@ -2,31 +2,71 @@ package android.permissionmultidevice.cts import android.content.Context import android.content.pm.PackageManager -import android.provider.Settings -import org.junit.Assert +import android.content.res.Configuration +import android.content.res.Resources +import android.permission.PermissionManager +import android.permission.PermissionManager.PermissionState +import android.util.Log +import com.android.compatibility.common.util.SystemUtil object PermissionUtils { - fun assertAppHasPermissionForDevice( + private val TAG = PermissionUtils::class.java.getSimpleName() + + fun getAllPermissionStates( context: Context, packageName: String, - permissionName: String, - deviceId: Int, - expectPermissionGranted: Boolean - ) { - val checkPermissionResult = - context - .createDeviceContext(deviceId) - .packageManager - .checkPermission(permissionName, packageName) - - if (expectPermissionGranted) { - Assert.assertEquals(PackageManager.PERMISSION_GRANTED, checkPermissionResult) - } else { - Assert.assertEquals(PackageManager.PERMISSION_DENIED, checkPermissionResult) + companionDeviceId: String + ): Map<String, PermissionState> { + val permissionManager = context.getSystemService(PermissionManager::class.java)!! + return SystemUtil.runWithShellPermissionIdentity<Map<String, PermissionState>> { + permissionManager.getAllPermissionStates(packageName, companionDeviceId) + } + } + + fun isAutomotive(context: Context): Boolean = + context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) + + fun isTv(context: Context): Boolean = + context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) + + fun isWatch(context: Context): Boolean = + context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH) + + /** + * This method checks for the minimum screen size described in CDD {@see + * https://source.android.com/docs/compatibility/14/android-14-cdd#7111_screen_size_and_shape} + */ + fun isCddCompliantScreenSize(): Boolean { + if ( + Resources.getSystem().configuration.uiMode and Configuration.UI_MODE_TYPE_MASK == + Configuration.UI_MODE_TYPE_WATCH + ) { + Log.d(TAG, "UI mode is UI_MODE_TYPE_WATCH, skipping the min dp check") + return true + } + + val screenSize = + Resources.getSystem().configuration.screenLayout and + Configuration.SCREENLAYOUT_SIZE_MASK + return when (screenSize) { + Configuration.SCREENLAYOUT_SIZE_SMALL -> hasMinScreenSize(426, 320) + Configuration.SCREENLAYOUT_SIZE_NORMAL -> hasMinScreenSize(480, 320) + Configuration.SCREENLAYOUT_SIZE_LARGE -> hasMinScreenSize(640, 480) + Configuration.SCREENLAYOUT_SIZE_XLARGE -> hasMinScreenSize(960, 720) + else -> { + Log.e(TAG, "Unknown screen size: $screenSize") + true + } } } - fun getHostDeviceName(context: Context): String { - return Settings.Global.getString(context.contentResolver, Settings.Global.DEVICE_NAME) + private fun hasMinScreenSize(minWidthDp: Int, minHeightDp: Int): Boolean { + val dpi = Resources.getSystem().displayMetrics.densityDpi + val widthDp = (160f / dpi) * Resources.getSystem().displayMetrics.widthPixels + val heightDp = (160f / dpi) * Resources.getSystem().displayMetrics.heightPixels + + // CDD does seem to follow width & height convention correctly, hence checking both ways + return (widthDp >= minWidthDp && heightDp >= minHeightDp) || + (widthDp >= minHeightDp && heightDp >= minWidthDp) } } diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt new file mode 100644 index 000000000..00df03e51 --- /dev/null +++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/AppPermissionsTest.kt @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.permissionmultidevice.cts + +import android.Manifest +import android.app.Instrumentation +import android.companion.virtual.VirtualDeviceManager +import android.companion.virtual.VirtualDeviceParams +import android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM +import android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Build +import android.permission.PermissionManager +import android.permission.flags.Flags +import android.permissionmultidevice.cts.PermissionUtils.isCddCompliantScreenSize +import android.platform.test.annotations.RequiresFlagsEnabled +import android.provider.Settings +import android.virtualdevice.cts.common.VirtualDeviceRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SdkSuppress +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiScrollable +import androidx.test.uiautomator.UiSelector +import com.android.compatibility.common.util.SystemUtil.eventually +import com.android.compatibility.common.util.UiAutomatorUtils2 +import com.android.modules.utils.build.SdkLevel +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Assume.assumeFalse +import org.junit.Assume.assumeTrue +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = "VanillaIceCream") +class AppPermissionsTest { + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + private val defaultDeviceContext = instrumentation.targetContext + + @get:Rule + var virtualDeviceRule = + VirtualDeviceRule.withAdditionalPermissions( + Manifest.permission.GRANT_RUNTIME_PERMISSIONS, + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS, + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, + Manifest.permission.CREATE_VIRTUAL_DEVICE + ) + + private lateinit var persistentDeviceId: String + private lateinit var externalDeviceCameraText: String + private lateinit var permissionMessage: String + + private val permissionManager = + defaultDeviceContext.getSystemService(PermissionManager::class.java)!! + + @Before + fun setup() { + assumeTrue(SdkLevel.isAtLeastV()) + assumeFalse(PermissionUtils.isAutomotive(defaultDeviceContext)) + assumeFalse(PermissionUtils.isTv(defaultDeviceContext)) + assumeFalse(PermissionUtils.isWatch(defaultDeviceContext)) + assumeTrue(isCddCompliantScreenSize()) + + PackageManagementUtils.installPackage(APP_APK_PATH_STREAMING) + + val virtualDeviceManager = + defaultDeviceContext.getSystemService(VirtualDeviceManager::class.java)!! + val virtualDevice = + virtualDeviceRule.createManagedVirtualDevice( + VirtualDeviceParams.Builder() + .setDevicePolicy(POLICY_TYPE_CAMERA, DEVICE_POLICY_CUSTOM) + .build() + ) + + val mDeviceDisplayName = + virtualDeviceManager.getVirtualDevice(virtualDevice.deviceId)!!.displayName.toString() + + persistentDeviceId = virtualDevice.persistentDeviceId!! + externalDeviceCameraText = "Camera on $mDeviceDisplayName" + permissionMessage = "Camera access for this app on $mDeviceDisplayName" + } + + @After + fun cleanup() { + PackageManagementUtils.uninstallPackage(APP_PACKAGE_NAME, requireSuccess = false) + UiAutomatorUtils2.getUiDevice().pressHome() + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun externalDevicePermissionGrantTest() { + grantRunTimePermission() + + openAppPermissionsScreen() + + val expectedGrantInfoMap = + mapOf( + "Allowed" to listOf(externalDeviceCameraText), + "Ask every time" to emptyList(), + "Not allowed" to listOf("Camera") + ) + assertEquals(expectedGrantInfoMap, getGrantInfoMap()) + + clickPermissionItem(externalDeviceCameraText) + + verifyPermissionMessage() + + verifyRadioButtonStates( + allowForegroundChecked = true, + askChecked = false, + denyChecked = false + ) + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun externalDevicePermissionChangeToAskTest() { + grantRunTimePermission() + openAppPermissionsScreen() + + clickPermissionItem(externalDeviceCameraText) + clickAskButton() + + verifyAskSelection() + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun externalDevicePermissionChangeToDenyTest() { + grantRunTimePermission() + openAppPermissionsScreen() + + clickPermissionItem(externalDeviceCameraText) + clickDenyButton() + + verifyDenySelection() + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun externalDevicePermissionChangeToAllowTest() { + grantRunTimePermission() + openAppPermissionsScreen() + + clickPermissionItem(externalDeviceCameraText) + clickAskButton() + verifyRadioButtonStates( + allowForegroundChecked = false, + askChecked = true, + denyChecked = false + ) + + clickAllowForegroundButton() + verifyAllowedSelection() + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun externalDevicePermissionNotDisplayedInitiallyTest() { + openAppPermissionsScreen() + + // External device permission does not show initially (until requested) + val expectedGrantInfoMap = + mapOf( + "Allowed" to emptyList(), + "Ask every time" to emptyList(), + "Not allowed" to listOf("Camera") + ) + assertEquals(expectedGrantInfoMap, getGrantInfoMap()) + } + + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) + @Test + fun externalDevicePermissionStickyOnGrantTest() { + grantRunTimePermission() + openAppPermissionsScreen() + + clickPermissionItem(externalDeviceCameraText) + + verifyRadioButtonStates( + allowForegroundChecked = true, + askChecked = false, + denyChecked = false + ) + + clickDenyButton() + + UiAutomatorUtils2.getUiDevice().pressBack() + + // Verify the permission continue to show (sticky) after revoking, keeps option for users + // to change in future + val expectedGrantInfoMap = + mapOf( + "Allowed" to emptyList(), + "Ask every time" to emptyList(), + "Not allowed" to listOf("Camera", externalDeviceCameraText) + ) + assertEquals(expectedGrantInfoMap, getGrantInfoMap()) + } + + private fun verifyAskSelection() { + verifyPermissionMessage() + + verifyRadioButtonStates( + allowForegroundChecked = false, + askChecked = true, + denyChecked = false + ) + + UiAutomatorUtils2.getUiDevice().pressBack() + + val expectedGrantInfoMap = + mapOf( + "Allowed" to emptyList(), + "Ask every time" to listOf(externalDeviceCameraText), + "Not allowed" to listOf("Camera") + ) + assertEquals(expectedGrantInfoMap, getGrantInfoMap()) + + val permState = getPermState() + assertEquals(false, permState[DEVICE_AWARE_PERMISSION]!!.isGranted) + assertTrue( + permState[DEVICE_AWARE_PERMISSION]!!.flags and + PackageManager.FLAG_PERMISSION_ONE_TIME != 0 + ) + } + + private fun verifyDenySelection() { + verifyPermissionMessage() + + verifyRadioButtonStates( + allowForegroundChecked = false, + askChecked = false, + denyChecked = true + ) + + UiAutomatorUtils2.getUiDevice().pressBack() + + val expectedGrantInfoMap = + mapOf( + "Allowed" to emptyList(), + "Ask every time" to emptyList(), + "Not allowed" to listOf("Camera", externalDeviceCameraText) + ) + assertEquals(expectedGrantInfoMap, getGrantInfoMap()) + + val permState = getPermState() + assertEquals(false, permState[DEVICE_AWARE_PERMISSION]!!.isGranted) + assertTrue( + permState[DEVICE_AWARE_PERMISSION]!!.flags and + PackageManager.FLAG_PERMISSION_USER_SET != 0 + ) + } + + private fun verifyAllowedSelection() { + verifyPermissionMessage() + + verifyRadioButtonStates( + allowForegroundChecked = true, + askChecked = false, + denyChecked = false + ) + + UiAutomatorUtils2.getUiDevice().pressBack() + + val expectedGrantInfoMap = + mapOf( + "Allowed" to listOf(externalDeviceCameraText), + "Ask every time" to emptyList(), + "Not allowed" to listOf("Camera") + ) + assertEquals(expectedGrantInfoMap, getGrantInfoMap()) + + val permState = getPermState() + assertEquals(true, permState[DEVICE_AWARE_PERMISSION]!!.isGranted) + assertTrue( + permState[DEVICE_AWARE_PERMISSION]!!.flags and + PackageManager.FLAG_PERMISSION_USER_SET != 0 + ) + } + + private fun verifyPermissionMessage() { + val actualText = UiAutomatorUtils2.waitFindObject(By.res(PERMISSION_MESSAGE_ID)).text + assertEquals(permissionMessage, actualText) + } + + private fun getGrantInfoMap(): Map<String, List<String>> { + val grantInfoMap = + mapOf( + "Allowed" to mutableListOf<String>(), + "Ask every time" to mutableListOf(), + "Not allowed" to mutableListOf() + ) + val outOfScopeTitles = setOf("Unused app settings", "Manage app if unused") + + val titleSelector = UiSelector().resourceId(TITLE) + var currentGrantText = "" + + val scrollable = getScrollableRecyclerView() + + // Scrolling to end inorder to have the scrollable object loaded with all child element data + // ready to be read. If the scroll happens in the middle of the reading process, it has been + // observed that child items will be skipped during the reading (could be a bug). Hence this + // solution is to scroll to the bottom in the beginning and be more efficient as well. + scrollable.scrollToEnd(1) + + for (i in 0..scrollable.childCount) { + val child = scrollable.getChild(UiSelector().index(i)) + val titleText = child.getChild(titleSelector).text + if (outOfScopeTitles.contains(titleText)) { + break + } + if (grantInfoMap.contains(titleText)) { + currentGrantText = titleText + } else if (!titleText.startsWith("No permissions")) { + grantInfoMap[currentGrantText]!!.add(titleText) + } + } + return grantInfoMap + } + + private fun verifyRadioButtonStates( + allowForegroundChecked: Boolean, + askChecked: Boolean, + denyChecked: Boolean + ) { + eventually { + assertEquals( + allowForegroundChecked, + UiAutomatorUtils2.waitFindObject(By.res(ALLOW_FOREGROUND_ONLY_RADIO_BUTTON)) + .isChecked + ) + assertEquals( + askChecked, + UiAutomatorUtils2.waitFindObject(By.res(ASK_RADIO_BUTTON)).isChecked + ) + assertEquals( + denyChecked, + UiAutomatorUtils2.waitFindObject(By.res(DENY_RADIO_BUTTON)).isChecked + ) + } + } + + private fun openAppPermissionsScreen() { + eventually { + instrumentation.context.startActivity( + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", APP_PACKAGE_NAME, null) + addCategory(Intent.CATEGORY_DEFAULT) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + } + ) + UiAutomatorUtils2.waitFindObject(By.text("Permissions"), 12000).click() + } + } + + private fun getScrollableRecyclerView(): UiScrollable { + // Wait for object to load + UiAutomatorUtils2.waitFindObject(By.res(RECYCLER_VIEW)) + return UiScrollable(UiSelector().resourceId(RECYCLER_VIEW)) + } + + private fun clickPermissionItem(permissionItemName: String) = + UiAutomatorUtils2.waitFindObject(By.text(permissionItemName)).click() + + private fun clickAllowForegroundButton() = + UiAutomatorUtils2.waitFindObject(By.res(ALLOW_FOREGROUND_ONLY_RADIO_BUTTON)).click() + + private fun clickAskButton() = + UiAutomatorUtils2.waitFindObject(By.res(ASK_RADIO_BUTTON)).click() + + private fun clickDenyButton() = + UiAutomatorUtils2.waitFindObject(By.res(DENY_RADIO_BUTTON)).click() + + private fun grantRunTimePermission() = + permissionManager.grantRuntimePermission( + APP_PACKAGE_NAME, + DEVICE_AWARE_PERMISSION, + persistentDeviceId + ) + + private fun getPermState(): Map<String, PermissionManager.PermissionState> = + permissionManager.getAllPermissionStates(APP_PACKAGE_NAME, persistentDeviceId) + + companion object { + private const val APK_DIRECTORY = "/data/local/tmp/cts-permissionmultidevice" + private const val APP_APK_PATH_STREAMING = + "${APK_DIRECTORY}/CtsAccessRemoteDeviceCamera.apk" + private const val APP_PACKAGE_NAME = + "android.permissionmultidevice.cts.accessremotedevicecamera" + private const val DEVICE_AWARE_PERMISSION = Manifest.permission.CAMERA + + private const val ALLOW_FOREGROUND_ONLY_RADIO_BUTTON = + "com.android.permissioncontroller:id/allow_foreground_only_radio_button" + private const val ASK_RADIO_BUTTON = "com.android.permissioncontroller:id/ask_radio_button" + private const val DENY_RADIO_BUTTON = + "com.android.permissioncontroller:id/deny_radio_button" + private const val TITLE = "android:id/title" + private const val RECYCLER_VIEW = "com.android.permissioncontroller:id/recycler_view" + private const val PERMISSION_MESSAGE_ID = + "com.android.permissioncontroller:id/permission_message" + } +} diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt index 09f4c7f08..191e69367 100644 --- a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt +++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt @@ -17,31 +17,37 @@ package android.permissionmultidevice.cts import android.Manifest -import android.app.ActivityOptions import android.app.Instrumentation +import android.companion.virtual.VirtualDeviceManager +import android.companion.virtual.VirtualDeviceParams +import android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM +import android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA import android.content.ComponentName import android.content.Intent import android.content.pm.PackageManager +import android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS +import android.hardware.display.DisplayManager +import android.hardware.display.VirtualDisplay import android.os.Build import android.permission.flags.Flags import android.permissionmultidevice.cts.PackageManagementUtils.installPackage import android.permissionmultidevice.cts.PackageManagementUtils.uninstallPackage -import android.permissionmultidevice.cts.PermissionUtils.assertAppHasPermissionForDevice -import android.permissionmultidevice.cts.PermissionUtils.getHostDeviceName import android.permissionmultidevice.cts.UiAutomatorUtils.click import android.permissionmultidevice.cts.UiAutomatorUtils.findTextForView import android.permissionmultidevice.cts.UiAutomatorUtils.waitFindObject +import android.platform.test.annotations.AppModeFull import android.platform.test.annotations.RequiresFlagsEnabled -import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.view.Display +import android.virtualdevice.cts.common.VirtualDeviceRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SdkSuppress import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By -import com.android.compatibility.common.util.AdoptShellPermissionsRule import com.android.compatibility.common.util.SystemUtil import com.google.common.truth.Truth import org.junit.After +import org.junit.Assert +import org.junit.Assume.assumeFalse import org.junit.Before import org.junit.Rule import org.junit.Test @@ -49,24 +55,49 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = "VanillaIceCream") +@AppModeFull(reason = "VirtualDeviceManager cannot be accessed by instant apps") class DeviceAwarePermissionGrantTest { private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() private val defaultDeviceContext = instrumentation.targetContext + private lateinit var mVirtualDeviceManager: VirtualDeviceManager + private lateinit var mVirtualDevice: VirtualDeviceManager.VirtualDevice + private lateinit var mVirtualDisplay: VirtualDisplay + private lateinit var mDeviceDisplayName: String - @get:Rule(order = 0) - val mAdoptShellPermissionsRule = - AdoptShellPermissionsRule( - instrumentation.uiAutomation, - Manifest.permission.CREATE_VIRTUAL_DEVICE - ) - - @get:Rule(order = 1) var mFakeVirtualDeviceRule = FakeVirtualDeviceRule() - - @Rule @JvmField val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() + @get:Rule var mVirtualDeviceRule = VirtualDeviceRule.createDefault() @Before fun setup() { + assumeFalse(PermissionUtils.isAutomotive(defaultDeviceContext)) + assumeFalse(PermissionUtils.isTv(defaultDeviceContext)) + assumeFalse(PermissionUtils.isWatch(defaultDeviceContext)) + installPackage(APP_APK_PATH_STREAMING) + mVirtualDeviceManager = + defaultDeviceContext.getSystemService(VirtualDeviceManager::class.java)!! + mVirtualDevice = + mVirtualDeviceRule.createManagedVirtualDevice( + VirtualDeviceParams.Builder() + .setDevicePolicy(POLICY_TYPE_CAMERA, DEVICE_POLICY_CUSTOM) + .build() + ) + + val displayConfig = + VirtualDeviceRule.createDefaultVirtualDisplayConfigBuilder( + DISPLAY_WIDTH, + DISPLAY_HEIGHT + ) + .setFlags( + DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC or + DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED or + DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY + ) + .build() + + mVirtualDisplay = + mVirtualDeviceRule.createManagedVirtualDisplay(mVirtualDevice, displayConfig)!! + mDeviceDisplayName = + mVirtualDeviceManager.getVirtualDevice(mVirtualDevice.deviceId)!!.displayName.toString() } @After @@ -74,7 +105,10 @@ class DeviceAwarePermissionGrantTest { uninstallPackage(APP_PACKAGE_NAME, requireSuccess = false) } - @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) @Test fun onHostDevice_requestPermissionForHostDevice_shouldGrantPermission() { testGrantPermissionForDevice( @@ -87,40 +121,45 @@ class DeviceAwarePermissionGrantTest { ) } - @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) @Test fun onHostDevice_requestPermissionForRemoteDevice_shouldGrantPermission() { testGrantPermissionForDevice( Display.DEFAULT_DISPLAY, - mFakeVirtualDeviceRule.virtualDevice.deviceId, + mVirtualDevice.deviceId, true, - DEFAULT_REMOTE_DEVICE_NAME, + mDeviceDisplayName, expectPermissionGrantedOnDefaultDevice = false, expectPermissionGrantedOnRemoteDevice = true ) } - @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) @Test - fun onRemoteDevice_requestPermissionForHostDevice_shouldGrantPermission() { - testGrantPermissionForDevice( - mFakeVirtualDeviceRule.virtualDisplayId, - DEVICE_ID_DEFAULT, - true, - getHostDeviceName(defaultDeviceContext), - expectPermissionGrantedOnDefaultDevice = true, - expectPermissionGrantedOnRemoteDevice = false - ) + fun onRemoteDevice_requestPermissionForHostDevice_shouldShowWarningDialog() { + requestPermissionOnDevice(mVirtualDisplay.display.displayId, DEVICE_ID_DEFAULT) + + val displayId = mVirtualDisplay.display.displayId + waitFindObject(By.displayId(displayId).textContains("Permission request suppressed")) } - @RequiresFlagsEnabled(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) + @RequiresFlagsEnabled( + Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED, + Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED + ) @Test fun onRemoteDevice_requestPermissionForRemoteDevice_shouldGrantPermission() { testGrantPermissionForDevice( - mFakeVirtualDeviceRule.virtualDisplayId, - mFakeVirtualDeviceRule.virtualDevice.deviceId, + mVirtualDisplay.display.displayId, + mVirtualDevice.deviceId, true, - DEFAULT_REMOTE_DEVICE_NAME, + mDeviceDisplayName, expectPermissionGrantedOnDefaultDevice = false, expectPermissionGrantedOnRemoteDevice = true ) @@ -134,23 +173,12 @@ class DeviceAwarePermissionGrantTest { expectPermissionGrantedOnDefaultDevice: Boolean, expectPermissionGrantedOnRemoteDevice: Boolean ) { - assertAppHasPermissionForDevice( - defaultDeviceContext, - APP_PACKAGE_NAME, - Manifest.permission.CAMERA, - DEVICE_ID_DEFAULT, - false - ) - - assertAppHasPermissionForDevice( - defaultDeviceContext, - APP_PACKAGE_NAME, - Manifest.permission.CAMERA, - mFakeVirtualDeviceRule.virtualDevice.deviceId, - false - ) + // Assert no permission granted to either default device or virtual device + assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false) + assertAppHasPermissionForDevice(mVirtualDevice.deviceId, false) requestPermissionOnDevice(displayId, targetDeviceId) + mVirtualDeviceRule.waitAndAssertActivityResumed(getPermissionDialogComponentName()) if (showDeviceName) { assertPermissionMessageContainsDeviceName(displayId, expectedDeviceNameInDialog) @@ -158,26 +186,14 @@ class DeviceAwarePermissionGrantTest { SystemUtil.eventually { click(By.displayId(displayId).res(ALLOW_BUTTON)) } + assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, expectPermissionGrantedOnDefaultDevice) assertAppHasPermissionForDevice( - defaultDeviceContext, - APP_PACKAGE_NAME, - Manifest.permission.CAMERA, - DEVICE_ID_DEFAULT, - expectPermissionGrantedOnDefaultDevice - ) - - assertAppHasPermissionForDevice( - defaultDeviceContext, - APP_PACKAGE_NAME, - Manifest.permission.CAMERA, - mFakeVirtualDeviceRule.virtualDevice.deviceId, + mVirtualDevice.deviceId, expectPermissionGrantedOnRemoteDevice ) } private fun requestPermissionOnDevice(displayId: Int, targetDeviceId: Int) { - val options = ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle() - val intent = Intent() .setComponent( @@ -185,7 +201,7 @@ class DeviceAwarePermissionGrantTest { ) .putExtra(PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, targetDeviceId) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) - defaultDeviceContext.startActivity(intent, options) + mVirtualDeviceRule.sendIntentToDisplay(intent, displayId) } private fun assertPermissionMessageContainsDeviceName(displayId: Int, deviceName: String) { @@ -194,14 +210,37 @@ class DeviceAwarePermissionGrantTest { Truth.assertThat(text).contains(deviceName) } + private fun assertAppHasPermissionForDevice(deviceId: Int, expectPermissionGranted: Boolean) { + val checkPermissionResult = + defaultDeviceContext + .createDeviceContext(deviceId) + .packageManager + .checkPermission(DEVICE_AWARE_PERMISSION, APP_PACKAGE_NAME) + + if (expectPermissionGranted) { + Assert.assertEquals(PackageManager.PERMISSION_GRANTED, checkPermissionResult) + } else { + Assert.assertEquals(PackageManager.PERMISSION_DENIED, checkPermissionResult) + } + } + + private fun getPermissionDialogComponentName(): ComponentName { + val intent = Intent(ACTION_REQUEST_PERMISSIONS) + intent.setPackage(defaultDeviceContext.packageManager.getPermissionControllerPackageName()) + return intent.resolveActivity(defaultDeviceContext.packageManager) + } + companion object { const val APK_DIRECTORY = "/data/local/tmp/cts-permissionmultidevice" const val APP_APK_PATH_STREAMING = "${APK_DIRECTORY}/CtsAccessRemoteDeviceCamera.apk" const val APP_PACKAGE_NAME = "android.permissionmultidevice.cts.accessremotedevicecamera" const val PERMISSION_MESSAGE_ID = "com.android.permissioncontroller:id/permission_message" - const val DEFAULT_REMOTE_DEVICE_NAME = "remote device" const val ALLOW_BUTTON = "com.android.permissioncontroller:id/permission_allow_foreground_only_button" const val DEVICE_ID_DEFAULT = 0 + const val PERSISTENT_DEVICE_ID_DEFAULT = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT + const val DEVICE_AWARE_PERMISSION = Manifest.permission.CAMERA + private const val DISPLAY_HEIGHT = 1920 + private const val DISPLAY_WIDTH = 1080 } } diff --git a/tests/cts/permissionmultiuser/Android.bp b/tests/cts/permissionmultiuser/Android.bp index f577c82e3..b86b02205 100644 --- a/tests/cts/permissionmultiuser/Android.bp +++ b/tests/cts/permissionmultiuser/Android.bp @@ -43,5 +43,6 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/permissionmultiuser/src/android/permissionmultiuser/cts/AppDataSharingUpdatesTest.kt b/tests/cts/permissionmultiuser/src/android/permissionmultiuser/cts/AppDataSharingUpdatesTest.kt index beade31ac..2169f0f72 100644 --- a/tests/cts/permissionmultiuser/src/android/permissionmultiuser/cts/AppDataSharingUpdatesTest.kt +++ b/tests/cts/permissionmultiuser/src/android/permissionmultiuser/cts/AppDataSharingUpdatesTest.kt @@ -52,14 +52,14 @@ import androidx.test.filters.SdkSuppress import androidx.test.platform.app.InstrumentationRegistry import com.android.bedstead.harrier.BedsteadJUnit4 import com.android.bedstead.harrier.DeviceState -import com.android.bedstead.harrier.annotations.EnsureHasPermission +import com.android.bedstead.permissions.annotations.EnsureHasPermission import com.android.bedstead.harrier.annotations.EnsureSecureSettingSet import com.android.bedstead.harrier.annotations.RequireDoesNotHaveFeature import com.android.bedstead.harrier.annotations.RequireNotWatch import com.android.bedstead.harrier.annotations.RequireRunOnAdditionalUser import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile import com.android.bedstead.harrier.annotations.RequireSdkVersion -import com.android.bedstead.nene.permissions.CommonPermissions.INTERACT_ACROSS_USERS +import com.android.bedstead.permissions.CommonPermissions.INTERACT_ACROSS_USERS import com.android.compatibility.common.util.ApiTest import com.android.compatibility.common.util.DeviceConfigStateChangerRule import com.android.compatibility.common.util.SystemUtil.runShellCommand diff --git a/tests/cts/permissionpolicy/Android.bp b/tests/cts/permissionpolicy/Android.bp index 127de939c..8f3c42b0e 100644 --- a/tests/cts/permissionpolicy/Android.bp +++ b/tests/cts/permissionpolicy/Android.bp @@ -25,7 +25,6 @@ android_test { test_suites: [ "cts", "general-tests", - "mts-permission", ], libs: ["android.test.base"], static_libs: [ @@ -36,6 +35,8 @@ android_test { "androidx.test.ext.junit-nodeps", "truth", "permission-test-util-lib", + "androidx.test.rules", + "flag-junit", ], srcs: [ "src/**/*.java", diff --git a/tests/cts/permissionpolicy/OWNERS b/tests/cts/permissionpolicy/OWNERS index 395269207..3f0256275 100644 --- a/tests/cts/permissionpolicy/OWNERS +++ b/tests/cts/permissionpolicy/OWNERS @@ -5,3 +5,4 @@ include platform/frameworks/base:/core/java/android/permission/OWNERS per-file NoLocationPermissionTest.java = tgunn@google.com per-file RestrictedStoragePermissionSharedUidTest.java = nandana@google.com per-file RestrictedStoragePermissionTest.java = nandana@google.com +per-file NoReceiveSmsPermissionTest.java = sasindran@google.com diff --git a/tests/cts/permissionpolicy/res/raw/android_manifest.xml b/tests/cts/permissionpolicy/res/raw/android_manifest.xml index e736e201a..35cbe6935 100644 --- a/tests/cts/permissionpolicy/res/raw/android_manifest.xml +++ b/tests/cts/permissionpolicy/res/raw/android_manifest.xml @@ -48,6 +48,7 @@ <protected-broadcast android:name="android.intent.action.CANCEL_ENABLE_ROLLBACK" /> <protected-broadcast android:name="android.intent.action.ROLLBACK_COMMITTED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_RESTARTED" /> + <protected-broadcast android:name="android.intent.action.PACKAGE_UNSTOPPED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_DATA_CLEARED" /> <protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" /> <protected-broadcast android:name="android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION" /> @@ -101,6 +102,7 @@ <protected-broadcast android:name="android.intent.action.OVERLAY_PRIORITY_CHANGED" /> <protected-broadcast android:name="android.intent.action.MY_PACKAGE_SUSPENDED" /> <protected-broadcast android:name="android.intent.action.MY_PACKAGE_UNSUSPENDED" /> + <protected-broadcast android:name="android.intent.action.UNARCHIVE_PACKAGE" /> <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" /> <protected-broadcast android:name="android.os.action.DEVICE_IDLE_MODE_CHANGED" /> @@ -144,6 +146,7 @@ <protected-broadcast android:name="android.appwidget.action.APPWIDGET_ENABLED" /> <protected-broadcast android:name="android.appwidget.action.APPWIDGET_HOST_RESTORED" /> <protected-broadcast android:name="android.appwidget.action.APPWIDGET_RESTORED" /> + <protected-broadcast android:name="android.appwidget.action.APPWIDGET_ENABLE_AND_UPDATE" /> <protected-broadcast android:name="android.os.action.SETTING_RESTORED" /> @@ -176,6 +179,7 @@ <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" /> <protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" /> <protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.device.action.REMOTE_ISSUE_OCCURRED" /> <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" /> <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" /> <protected-broadcast @@ -201,6 +205,8 @@ <protected-broadcast android:name="android.bluetooth.headsetclient.profile.action.LAST_VTAG" /> <protected-broadcast + android:name="android.bluetooth.headsetclient.profile.action.NETWORK_SERVICE_STATE_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.hearingaid.profile.action.PLAYING_STATE_CHANGED" /> @@ -257,6 +263,7 @@ android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY" /> <protected-broadcast android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.action.HAP_CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.action.LE_AUDIO_CONF_CHANGED" /> @@ -292,6 +299,7 @@ <protected-broadcast android:name="android.hardware.usb.action.USB_STATE" /> <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_CHANGED" /> + <protected-broadcast android:name="android.hardware.usb.action.USB_PORT_COMPLIANCE_CHANGED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_DETACHED" /> <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE" /> @@ -313,6 +321,7 @@ <protected-broadcast android:name="android.media.MASTER_BALANCE_CHANGED_ACTION" /> <protected-broadcast android:name="android.media.SCO_AUDIO_STATE_CHANGED" /> <protected-broadcast android:name="android.media.ACTION_SCO_AUDIO_STATE_UPDATED" /> + <protected-broadcast android:name="com.android.server.audio.action.CHECK_MUSIC_ACTIVE" /> <protected-broadcast android:name="android.intent.action.MEDIA_REMOVED" /> <protected-broadcast android:name="android.intent.action.MEDIA_UNMOUNTED" /> @@ -377,6 +386,8 @@ <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED" /> <protected-broadcast android:name="com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED" /> <protected-broadcast android:name="com.android.internal.action.EUICC_FACTORY_RESET" /> + <protected-broadcast + android:name="com.android.internal.action.EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS" /> <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" /> <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" /> <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" /> @@ -400,6 +411,7 @@ <protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" /> <protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" /> <protected-broadcast android:name="android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED" /> + <protected-broadcast android:name="android.net.wifi.aware.action.WIFI_AWARE_RESOURCE_CHANGED" /> <protected-broadcast android:name="android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED" /> <protected-broadcast android:name="android.net.wifi.SCAN_RESULTS" /> <protected-broadcast android:name="android.net.wifi.RSSI_CHANGED" /> @@ -470,11 +482,9 @@ android:name="com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION" /> <!-- Defined in RestrictionsManager --> - <protected-broadcast - android:name="android.intent.action.PERMISSION_RESPONSE_RECEIVED" /> - <!-- Defined in RestrictionsManager --> + <protected-broadcast android:name="android.content.action.PERMISSION_RESPONSE_RECEIVED" /> + <protected-broadcast android:name="android.content.action.REQUEST_PERMISSION" /> - <protected-broadcast android:name="android.intent.action.REQUEST_PERMISSION" /> <protected-broadcast android:name="android.nfc.handover.intent.action.HANDOVER_STARTED" /> <protected-broadcast android:name="android.nfc.handover.intent.action.TRANSFER_DONE" /> <protected-broadcast android:name="android.nfc.handover.intent.action.TRANSFER_PROGRESS" /> @@ -525,6 +535,7 @@ <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_ADDED" /> <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNLOCKED" /> <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_REMOVED" /> + <protected-broadcast android:name="android.app.action.MANAGED_PROFILE_PROVISIONED" /> <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_STATE_CHANGED" /> <protected-broadcast android:name="com.android.bluetooth.map.USER_CONFIRM_TIMEOUT" /> @@ -567,6 +578,7 @@ <protected-broadcast android:name="com.android.settings.network.SWITCH_TO_SUBSCRIPTION" /> <protected-broadcast android:name="com.android.settings.wifi.action.NETWORK_REQUEST" /> + <protected-broadcast android:name="android.app.action.KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED" /> <protected-broadcast android:name="NotificationManagerService.TIMEOUT" /> <protected-broadcast android:name="NotificationHistoryDatabase.CLEANUP" /> <protected-broadcast android:name="ScheduleConditionProvider.EVALUATE" /> @@ -652,6 +664,8 @@ <protected-broadcast android:name="android.intent.action.DEVICE_LOCKED_CHANGED" /> + <protected-broadcast android:name="com.android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED"/> + <!-- Added in O --> <protected-broadcast android:name="android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED" /> <protected-broadcast android:name="com.android.server.wm.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION" /> @@ -663,7 +677,6 @@ <protected-broadcast android:name="android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED" /> <protected-broadcast android:name="android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" /> <protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" /> - <protected-broadcast android:name="com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" /> <!-- Made protected in P (was introduced in JB-MR2) --> <protected-broadcast android:name="android.intent.action.GET_RESTRICTION_ENTRIES" /> @@ -791,14 +804,40 @@ <protected-broadcast android:name="android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED" /> <protected-broadcast android:name="com.android.phone.settings.CARRIER_PROVISIONING" /> <protected-broadcast android:name="com.android.phone.settings.TRIGGER_CARRIER_PROVISIONING" /> + <protected-broadcast android:name="com.android.internal.telephony.ACTION_VOWIFI_ENABLED" /> <protected-broadcast android:name="android.telephony.action.ANOMALY_REPORTED" /> <protected-broadcast android:name="android.intent.action.SUBSCRIPTION_INFO_RECORD_ADDED" /> <protected-broadcast android:name="android.intent.action.ACTION_MANAGED_ROAMING_IND" /> <protected-broadcast android:name="android.telephony.ims.action.RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE" /> <!-- Added in T --> + <protected-broadcast android:name="android.safetycenter.action.REFRESH_SAFETY_SOURCES" /> + <protected-broadcast android:name="android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED" /> + <protected-broadcast android:name="android.app.action.DEVICE_POLICY_RESOURCE_UPDATED" /> + <protected-broadcast android:name="android.intent.action.SHOW_FOREGROUND_SERVICE_MANAGER" /> + <protected-broadcast android:name="android.service.autofill.action.DELAYED_FILL" /> + <protected-broadcast android:name="android.app.action.PROVISIONING_COMPLETED" /> <protected-broadcast android:name="android.app.action.LOST_MODE_LOCATION_UPDATE" /> + <!-- Added in U --> + <protected-broadcast android:name="android.intent.action.PROFILE_ADDED" /> + <protected-broadcast android:name="android.intent.action.PROFILE_REMOVED" /> + <protected-broadcast android:name="com.android.internal.telephony.cat.SMS_SENT_ACTION" /> + <protected-broadcast android:name="com.android.internal.telephony.cat.SMS_DELIVERY_ACTION" /> + <protected-broadcast android:name="com.android.internal.telephony.data.ACTION_RETRY" /> + <protected-broadcast android:name="android.companion.virtual.action.VIRTUAL_DEVICE_REMOVED" /> + <protected-broadcast android:name="com.android.internal.intent.action.FLASH_NOTIFICATION_START_PREVIEW" /> + <protected-broadcast android:name="com.android.internal.intent.action.FLASH_NOTIFICATION_STOP_PREVIEW" /> + <protected-broadcast android:name="android.app.admin.action.DEVICE_FINANCING_STATE_CHANGED" /> + <protected-broadcast android:name="android.app.admin.action.DEVICE_POLICY_SET_RESULT" /> + <protected-broadcast android:name="android.app.admin.action.DEVICE_POLICY_CHANGED" /> + + <!-- Added in V --> + <protected-broadcast android:name="android.intent.action.PROFILE_AVAILABLE" /> + <protected-broadcast android:name="android.intent.action.PROFILE_UNAVAILABLE" /> + <protected-broadcast android:name="android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED" /> + <protected-broadcast android:name="android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED" /> + <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> @@ -833,6 +872,7 @@ android:label="@string/permlab_readContacts" android:description="@string/permdesc_readContacts" android:protectionLevel="dangerous" /> + <uses-permission android:name="android.permission.READ_CONTACTS" /> <!-- Allows an application to write the user's contacts data. <p>Protection level: dangerous @@ -843,6 +883,20 @@ android:description="@string/permdesc_writeContacts" android:protectionLevel="dangerous" /> + <!-- Allows an app to update the verification status of E2EE contact keys owned by other apps. + <p>This permission is only granted to system apps. + <p>Protection level: signature|privileged + @SystemApi + @hide + @FlaggedApi("android.provider.user_keys") + --> + <permission android:name="android.permission.WRITE_VERIFICATION_STATE_E2EE_CONTACT_KEYS" + android:permissionGroup="android.permission-group.UNDEFINED" + android:label="@string/permlab_writeVerificationStateE2eeContactKeys" + android:description="@string/permdesc_writeVerificationStateE2eeContactKeys" + android:protectionLevel="signature|privileged" + android:featureFlag="android.provider.user_keys" /> + <!-- Allows an application to set default account for new contacts. <p> This permission is only granted to system applications fulfilling the Contacts app role. <p>Protection level: internal|role @@ -903,7 +957,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.SEND_SMS" @@ -917,7 +971,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.RECEIVE_SMS" @@ -931,7 +985,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.READ_SMS" @@ -945,7 +999,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.RECEIVE_WAP_PUSH" @@ -959,7 +1013,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.RECEIVE_MMS" @@ -994,7 +1048,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. @hide Pending API council approval --> @@ -1006,20 +1060,10 @@ android:protectionLevel="dangerous" /> <!-- @SystemApi @hide Allows an application to communicate over satellite. - Only granted if the application is a system app.--> + Only granted if the application is a system app or privileged app. --> <permission android:name="android.permission.SATELLITE_COMMUNICATION" android:protectionLevel="role|signature|privileged" /> - <!-- @SystemApi @hide Allows an application to bind with satellite service. - Only granted if the application is a system app.--> - <permission android:name="android.permission.BIND_SATELLITE_SERVICE" - android:protectionLevel="signature|privileged|vendorPrivileged" /> - - <!-- @hide Allows an application to bind with satellite gateway service. - Only granted if the application is a system app.--> - <permission android:name="android.permission.BIND_SATELLITE_GATEWAY_SERVICE" - android:protectionLevel="signature" /> - <!-- ====================================================================== --> <!-- Permissions for accessing external storage --> <!-- ====================================================================== --> @@ -1033,28 +1077,41 @@ android:priority="900" /> <!-- Allows an application to read from external storage. - <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly - granted this permission.</p> + <p class="note"><strong>Note: </strong>Starting in API level 33, this permission has no + effect. If your app accesses other apps' media files, request one or more of these permissions + instead: <a href="#READ_MEDIA_IMAGES"><code>READ_MEDIA_IMAGES</code></a>, + <a href="#READ_MEDIA_VIDEO"><code>READ_MEDIA_VIDEO</code></a>, + <a href="#READ_MEDIA_AUDIO"><code>READ_MEDIA_AUDIO</code></a>. Learn more about the + <a href="{@docRoot}training/data-storage/shared/media#storage-permission">storage + permissions</a> that are associated with media files.</p> + <p>This permission is enforced starting in API level 19. Before API level 19, this permission is not enforced and all apps still have access to read from external storage. You can test your app with the permission enforced by enabling <em>Protect USB - storage</em> under Developer options in the Settings app on a device running Android 4.1 or - higher.</p> + storage</em> under <b>Developer options</b> in the Settings app on a device running Android + 4.1 or higher.</p> <p>Also starting in API level 19, this permission is <em>not</em> required to - read/write files in your application-specific directories returned by + read or write files in your application-specific directories returned by {@link android.content.Context#getExternalFilesDir} and - {@link android.content.Context#getExternalCacheDir}. - <p class="note"><strong>Note:</strong> If <em>both</em> your <a + {@link android.content.Context#getExternalCacheDir}.</p> + <p>Starting in API level 29, apps don't need to request this permission to access files in + their app-specific directory on external storage, or their own files in the + <a href="{@docRoot}reference/android/provider/MediaStore"><code>MediaStore</code></a>. Apps + shouldn't request this permission unless they need to access other apps' files in the + <code>MediaStore</code>. Read more about these changes in the + <a href="{@docRoot}training/data-storage#scoped-storage">scoped storage</a> section of the + developer documentation.</p> + <p>If <em>both</em> your <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> and <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> values are set to 3 or lower, the system implicitly grants your app this permission. If you don't need this permission, be sure your <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code - targetSdkVersion}</a> is 4 or higher. + targetSdkVersion}</a> is 4 or higher.</p> <p> This is a soft restricted permission which cannot be held by an app it its - full form until the installer on record whitelists the permission. + full form until the installer on record allowlists the permission. Specifically, if the permission is allowlisted the holder app can access external storage and the visual and aural media collections while if the permission is not allowlisted the holder app can only access to the visual @@ -1080,10 +1137,12 @@ <!-- Allows an application to read audio files from external storage. <p>This permission is enforced starting in API level - {@link android.os.Build.VERSION_CODES#TIRAMISU}. + {@link android.os.Build.VERSION_CODES#TIRAMISU}. An app which targets + {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher and needs to read audio files from + external storage must hold this permission; {@link #READ_EXTERNAL_STORAGE} is not required. For apps with a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code - targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission - must not be used and the READ_EXTERNAL_STORAGE permission must be used instead. + targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S_V2} or lower, the + {@link #READ_EXTERNAL_STORAGE} permission is required, instead, to read audio files. <p>Protection level: dangerous --> <permission android:name="android.permission.READ_MEDIA_AUDIO" android:permissionGroup="android.permission-group.UNDEFINED" @@ -1099,12 +1158,14 @@ android:description="@string/permgroupdesc_readMediaVisual" android:priority="1000" /> - <!-- Allows an application to read audio files from external storage. - <p>This permission is enforced starting in API level - {@link android.os.Build.VERSION_CODES#TIRAMISU}. - For apps with a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code - targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission - must not be used and the READ_EXTERNAL_STORAGE permission must be used instead. + <!-- Allows an application to read video files from external storage. + <p>This permission is enforced starting in API level + {@link android.os.Build.VERSION_CODES#TIRAMISU}. An app which targets + {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher and needs to read video files from + external storage must hold this permission; {@link #READ_EXTERNAL_STORAGE} is not required. + For apps with a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code + targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S_V2} or lower, the + {@link #READ_EXTERNAL_STORAGE} permission is required, instead, to read video files. <p>Protection level: dangerous --> <permission android:name="android.permission.READ_MEDIA_VIDEO" android:permissionGroup="android.permission-group.UNDEFINED" @@ -1114,22 +1175,32 @@ <!-- Allows an application to read image files from external storage. <p>This permission is enforced starting in API level - {@link android.os.Build.VERSION_CODES#TIRAMISU}. + {@link android.os.Build.VERSION_CODES#TIRAMISU}. An app which targets + {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher and needs to read image files from + external storage must hold this permission; {@link #READ_EXTERNAL_STORAGE} is not required. For apps with a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code - targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission - must not be used and the READ_EXTERNAL_STORAGE permission must be used instead. - <p>Protection level: dangerous --> + targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S_V2} or lower, the + {@link #READ_EXTERNAL_STORAGE} permission is required, instead, to read image files. + <p>Protection level: dangerous --> <permission android:name="android.permission.READ_MEDIA_IMAGES" android:permissionGroup="android.permission-group.UNDEFINED" - android:label="@string/permlab_readMediaImage" - android:description="@string/permdesc_readMediaImage" + android:label="@string/permlab_readMediaImages" + android:description="@string/permdesc_readMediaImages" android:protectionLevel="dangerous" /> <!-- Allows an application to read image or video files from external storage that a user has selected via the permission prompt photo picker. Apps can check this permission to verify that a user has decided to use the photo picker, instead of granting access to - {@link #READ_MEDIA_IMAGES or #READ_MEDIA_VIDEO}. It does not prevent apps from accessing the - standard photo picker manually. + {@link #READ_MEDIA_IMAGES} or {@link #READ_MEDIA_VIDEO}. It does not prevent apps from + accessing the standard photo picker manually. This permission should be requested alongside + {@link #READ_MEDIA_IMAGES} and/or {@link #READ_MEDIA_VIDEO}, depending on which type of media + is desired. + <p> This permission will be automatically added to an app's manifest if the app requests + {@link #READ_MEDIA_IMAGES}, {@link #READ_MEDIA_VIDEO}, or {@link #ACCESS_MEDIA_LOCATION} + regardless of target SDK. If an app does not request this permission, then the grant dialog + will return `PERMISSION_GRANTED` for {@link #READ_MEDIA_IMAGES} and/or + {@link #READ_MEDIA_VIDEO}, but the app will only have access to the media selected by the + user. This false grant state will persist until the app goes into the background. <p>Protection level: dangerous --> <permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" android:permissionGroup="android.permission-group.UNDEFINED" @@ -1138,7 +1209,28 @@ android:protectionLevel="dangerous" /> <!-- Allows an application to write to external storage. - <p class="note"><strong>Note:</strong> If <em>both</em> your <a + <p><strong>Note: </strong>If your app targets {@link android.os.Build.VERSION_CODES#R} or + higher, this permission has no effect. + + <p>If your app is on a device that runs API level 19 or higher, you don't need to declare + this permission to read and write files in your application-specific directories returned + by {@link android.content.Context#getExternalFilesDir} and + {@link android.content.Context#getExternalCacheDir}. + + <p>Learn more about how to + <a href="{@docRoot}training/data-storage/shared/media#update-other-apps-files">modify media + files</a> that your app doesn't own, and how to + <a href="{@docRoot}training/data-storage/shared/documents-files">modify non-media files</a> + that your app doesn't own. + + <p>If your app is a file manager and needs broad access to external storage files, then + the system must place your app on an allowlist so that you can successfully request the + <a href="#MANAGE_EXTERNAL_STORAGE><code>MANAGE_EXTERNAL_STORAGE</code></a> permission. + Learn more about the appropriate use cases for + <a href="{@docRoot}training/data-storage/manage-all-files>managing all files on a storage + device</a>. + + <p>If <em>both</em> your <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> and <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code @@ -1146,12 +1238,6 @@ grants your app this permission. If you don't need this permission, be sure your <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> is 4 or higher. - <p>Starting in API level 19, this permission is <em>not</em> required to - read/write files in your application-specific directories returned by - {@link android.content.Context#getExternalFilesDir} and - {@link android.content.Context#getExternalCacheDir}. - <p>If this permission is not allowlisted for an app that targets an API level before - {@link android.os.Build.VERSION_CODES#Q} this permission cannot be granted to apps.</p> <p>Protection level: dangerous</p> --> <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" @@ -1240,7 +1326,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" @@ -1302,7 +1388,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.READ_CALL_LOG" @@ -1312,8 +1398,7 @@ android:permissionFlags="hardRestricted" android:protectionLevel="dangerous" /> - <!-- Allows an application to write (but not read) the user's - call log data. + <!-- Allows an application to write and read the user's call log data. <p class="note"><strong>Note:</strong> If your app uses the {@link #WRITE_CONTACTS} permission and <em>both</em> your <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code @@ -1326,7 +1411,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.WRITE_CALL_LOG" @@ -1342,7 +1427,7 @@ <p>Protection level: dangerous <p> This is a hard restricted permission which cannot be held by an app until - the installer on record whitelists the permission. For more details see + the installer on record allowlists the permission. For more details see {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. @deprecated Applications should use {@link android.telecom.CallRedirectionService} instead @@ -1386,6 +1471,14 @@ android:description="@string/permdesc_readPhoneState" android:protectionLevel="dangerous" /> + <!-- Allows read only access to phone state with a non dangerous permission, + including the information like cellular network type, software version. --> + <permission android:name="android.permission.READ_BASIC_PHONE_STATE" + android:permissionGroup="android.permission-group.UNDEFINED" + android:label="@string/permlab_readBasicPhoneState" + android:description="@string/permdesc_readBasicPhoneState" + android:protectionLevel="normal" /> + <!-- Allows read access to the device's phone number(s). This is a subset of the capabilities granted by {@link #READ_PHONE_STATE} but is exposed to instant applications. <p>Protection level: dangerous--> @@ -1397,7 +1490,9 @@ <!-- Allows an application to initiate a phone call without going through the Dialer user interface for the user to confirm the call. - <p>Protection level: dangerous + <p class="note"><b>Note:</b> An app holding this permission can also call carrier MMI + codes to change settings such as call forwarding or call waiting preferences.</p> + <p>Protection level: dangerous</p> --> <permission android:name="android.permission.CALL_PHONE" android:permissionGroup="android.permission-group.UNDEFINED" @@ -1630,12 +1725,24 @@ <!-- @SystemApi Allows camera access by Headless System User 0 when device is running in HSUM Mode. + @FlaggedApi("com.android.internal.camera.flags.camera_hsum_permission") @hide --> <permission android:name="android.permission.CAMERA_HEADLESS_SYSTEM_USER" android:permissionGroup="android.permission-group.UNDEFINED" android:label="@string/permlab_cameraHeadlessSystemUser" android:description="@string/permdesc_cameraHeadlessSystemUser" - android:protectionLevel="signature" /> + android:protectionLevel="signature" + android:featureFlag="com.android.internal.camera.flags.camera_hsum_permission" /> + + + <!-- @SystemApi Allows camera access of allowlisted driver assistance apps + to be controlled separately. + <p> Not for use by third-party applications. + @FlaggedApi("com.android.internal.camera.flags.camera_privacy_allowlist") + @hide + --> + <permission android:name="android.permission.CAMERA_PRIVACY_ALLOWLIST" + android:protectionLevel="signature|privileged" /> <!-- ====================================================================== --> <!-- Permissions for accessing the device sensors --> @@ -1663,11 +1770,11 @@ measure what is happening inside their body, such as heart rate. <p>Protection level: dangerous --> <permission android:name="android.permission.BODY_SENSORS" - android:permissionGroup="android.permission-group.UNDEFINED" - android:label="@string/permlab_bodySensors" - android:description="@string/permdesc_bodySensors" - android:backgroundPermission="android.permission.BODY_SENSORS_BACKGROUND" - android:protectionLevel="dangerous" /> + android:permissionGroup="android.permission-group.UNDEFINED" + android:label="@string/permlab_bodySensors" + android:description="@string/permdesc_bodySensors" + android:backgroundPermission="android.permission.BODY_SENSORS_BACKGROUND" + android:protectionLevel="dangerous" /> <!-- Allows an application to access data from sensors that the user uses to measure what is happening inside their body, such as heart rate. If you're requesting this permission, you @@ -1680,11 +1787,11 @@ {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}. --> <permission android:name="android.permission.BODY_SENSORS_BACKGROUND" - android:permissionGroup="android.permission-group.UNDEFINED" - android:label="@string/permlab_bodySensors_background" - android:description="@string/permdesc_bodySensors_background" - android:protectionLevel="dangerous" - android:permissionFlags="hardRestricted" /> + android:permissionGroup="android.permission-group.UNDEFINED" + android:label="@string/permlab_bodySensors_background" + android:description="@string/permdesc_bodySensors_background" + android:protectionLevel="dangerous" + android:permissionFlags="hardRestricted" /> <!-- Allows an app to use fingerprint hardware. <p>Protection level: normal @@ -1706,7 +1813,7 @@ android:description="@string/permdesc_useBiometric" android:protectionLevel="normal" /> - <!-- ======================================================================= --> + <!-- ====================================================================== --> <!-- Permissions for posting notifications --> <!-- ====================================================================== --> <eat-comment /> @@ -1727,6 +1834,7 @@ android:label="@string/permlab_postNotification" android:description="@string/permdesc_postNotification" android:protectionLevel="dangerous|instant" /> + <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- ====================================================================== --> <!-- REMOVED PERMISSIONS --> @@ -1762,7 +1870,7 @@ android:protectionLevel="normal" android:permissionFlags="removed"/> - <!-- @hide We need to keep this around for backwards compatibility --> + <!-- @SystemApi @hide We need to keep this around for backwards compatibility --> <permission android:name="android.permission.WRITE_SMS" android:protectionLevel="normal" android:permissionFlags="removed"/> @@ -1840,7 +1948,7 @@ <permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST" android:protectionLevel="signature|privileged" /> - <!-- Allows an application to monitor incoming Bluetooth MAP messages, to record + <!-- @SystemApi Allows an application to monitor incoming Bluetooth MAP messages, to record or perform processing on them. --> <!-- @hide --> <permission android:name="android.permission.RECEIVE_BLUETOOTH_MAP" @@ -1954,7 +2062,8 @@ <permission android:name="android.permission.ACCESS_MOCK_LOCATION" android:protectionLevel="signature" /> - <!-- @SystemApi @hide Allows automotive applications to control location + <!-- @hide @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) + Allows automotive applications to control location suspend state for power management use cases. <p>Not for use by third-party applications. --> @@ -1999,10 +2108,10 @@ android:protectionLevel="normal" /> <!-- This permission is used to let OEMs grant their trusted app access to a subset of - privileged wifi APIs to improve wifi performance. Allows applications to manage - Wi-Fi network selection related features such as enable or disable global auto-join, - modify connectivity scan intervals, and approve Wi-Fi Direct connections. - <p>Not for use by third-party applications. --> + privileged wifi APIs to improve wifi performance. Allows applications to manage + Wi-Fi network selection related features such as enable or disable global auto-join, + modify connectivity scan intervals, and approve Wi-Fi Direct connections. + <p>Not for use by third-party applications. --> <permission android:name="android.permission.MANAGE_WIFI_NETWORK_SELECTION" android:protectionLevel="signature|privileged|knownSigner" android:knownCerts="@array/wifi_known_signers" /> @@ -2061,14 +2170,14 @@ modifications. <p>Not for use by third-party applications. --> <permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" - android:protectionLevel="signature|privileged|knownSigner" - android:knownCerts="@array/wifi_known_signers" /> + android:protectionLevel="signature|privileged|knownSigner" + android:knownCerts="@array/wifi_known_signers" /> - <!-- Allows applications to act as network scorers. @hide @SystemApi--> + <!-- @deprecated Allows applications to act as network scorers. @hide @SystemApi--> <permission android:name="android.permission.SCORE_NETWORKS" android:protectionLevel="signature|privileged" /> - <!-- Allows applications to request network + <!-- @deprecated Allows applications to request network recommendations and scores from the NetworkScoreService. @SystemApi <p>Not for use by third-party applications. @hide --> @@ -2172,7 +2281,7 @@ <!-- @SystemApi @hide Allows changing Thread network state and access to Thread network credentials such as Network Key and PSKc. <p>Not for use by third-party applications. - @FlaggedApi("com.android.net.thread.flags.thread_enabled") --> + @FlaggedApi("com.android.net.thread.platform.flags.thread_enabled_platform") --> <permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED" android:protectionLevel="signature|privileged" /> @@ -2222,10 +2331,12 @@ <!-- Allows system apps to call methods to register itself as a mDNS offload engine. <p>Not for use by third-party or privileged applications. @SystemApi + @FlaggedApi("android.net.platform.flags.register_nsd_offload_engine") @hide This should only be used by system apps. --> <permission android:name="android.permission.REGISTER_NSD_OFFLOAD_ENGINE" - android:protectionLevel="signature" /> + android:protectionLevel="signature" + android:featureFlag="android.net.platform.flags.register_nsd_offload_engine" /> <!-- ======================================= --> <!-- Permissions for short range, peripheral networks --> @@ -2294,7 +2405,8 @@ them from running without explicit user action. --> <permission android:name="android.permission.QUARANTINE_APPS" - android:protectionLevel="signature|verifier" /> + android:protectionLevel="signature|verifier" + android:featureFlag="android.content.pm.quarantined_enabled" /> <!-- Allows applications to discover and pair bluetooth devices. <p>Protection level: normal @@ -2310,14 +2422,15 @@ <permission android:name="android.permission.BLUETOOTH_PRIVILEGED" android:protectionLevel="signature|privileged" /> - <!-- SystemApi Control access to email providers exclusively for Bluetooth + <!-- @SystemApi Control access to email providers exclusively for Bluetooth @hide --> <permission android:name="android.permission.BLUETOOTH_MAP" android:protectionLevel="signature|role" /> <!-- Allows bluetooth stack to access files - @hide This should only be used by Bluetooth apk. + This should only be granted to the Bluetooth apk. + @hide @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) --> <permission android:name="android.permission.BLUETOOTH_STACK" android:protectionLevel="signature|role" /> @@ -2340,6 +2453,8 @@ <p>Protection level: normal --> <permission android:name="android.permission.NFC_TRANSACTION_EVENT" + android:description="@string/permdesc_nfcTransactionEvent" + android:label="@string/permlab_nfcTransactionEvent" android:protectionLevel="normal" /> <!-- Allows applications to receive NFC preferred payment service information. @@ -2405,8 +2520,9 @@ <permission android:name="android.permission.NFC_HANDOVER_STATUS" android:protectionLevel="signature|privileged" /> - <!-- @hide Allows internal management of Bluetooth state when on wireless consent mode. - <p>Not for use by third-party applications. --> + <!-- @SystemApi Allows internal management of Bluetooth state when on wireless consent mode. + <p>Not for use by third-party applications. + @hide --> <permission android:name="android.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED" android:protectionLevel="signature" /> @@ -2502,6 +2618,15 @@ android:description="@string/permdesc_transmitIr" android:protectionLevel="normal" /> + <!-- Allows an app to turn on the screen on, e.g. with + {@link android.os.PowerManager#ACQUIRE_CAUSES_WAKEUP}. + <p>Intended to only be used by home automation apps. + --> + <permission android:name="android.permission.TURN_SCREEN_ON" + android:label="@string/permlab_turnScreenOn" + android:description="@string/permdesc_turnScreenOn" + android:protectionLevel="signature|privileged|appop" /> + <!-- ==================================================== --> <!-- Permissions related to changing audio settings --> <!-- ==================================================== --> @@ -2528,7 +2653,7 @@ <permission android:name="android.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE" android:protectionLevel="internal|role" /> - <!-- Allows an application to be notified whenever a screen capture is attempted. + <!-- Allows an application to get notified when a screen capture of its windows is attempted. <p>Protection level: normal --> <permission android:name="android.permission.DETECT_SCREEN_CAPTURE" @@ -2536,6 +2661,14 @@ android:description="@string/permdesc_detectScreenCapture" android:protectionLevel="normal" /> + <!-- Allows an application to get notified when it is being recorded. + <p>Protection level: normal + @FlaggedApi("com.android.window.flags.screen_recording_callbacks") + --> + <permission android:name="android.permission.DETECT_SCREEN_RECORDING" + android:protectionLevel="normal" + android:featureFlag="com.android.window.flags.screen_recording_callbacks" /> + <!-- ======================================== --> <!-- Permissions for factory reset protection --> <!-- ======================================== --> @@ -2656,6 +2789,12 @@ <permission android:name="android.permission.OEM_UNLOCK_STATE" android:protectionLevel="signature" /> + <!-- @SystemApi Allows configuration of factory reset protection + @FlaggedApi("android.security.frp_enforcement") + @hide <p>Not for use by third-party applications. --> + <permission android:name="android.permission.CONFIGURE_FACTORY_RESET_PROTECTION" + android:protectionLevel="signature|privileged" /> + <!-- @SystemApi @hide Allows querying state of PersistentDataBlock <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCESS_PDB_STATE" @@ -2763,6 +2902,13 @@ <permission android:name="android.permission.BIND_INCALL_SERVICE" android:protectionLevel="signature|privileged" /> + <!-- Must be required by a {@link android.telecom.CallStreamingService}, + to ensure that only the system can bind to it. + <p>Protection level: signature + @SystemApi @hide--> + <permission android:name="android.permission.BIND_CALL_STREAMING_SERVICE" + android:protectionLevel="signature" /> + <!-- Allows to query ongoing call details and manage ongoing calls <p>Protection level: signature|appop --> <permission android:name="android.permission.MANAGE_ONGOING_CALLS" @@ -2816,13 +2962,6 @@ <permission android:name="android.permission.BIND_CALL_REDIRECTION_SERVICE" android:protectionLevel="signature|privileged" /> - <!-- Must be required by a {@link android.telecom.CallStreamingService}, - to ensure that only the system can bind to it. - <p>Protection level: signature - @SystemApi @hide--> - <permission android:name="android.permission.BIND_CALL_STREAMING_SERVICE" - android:protectionLevel="signature" /> - <!-- Must be required by a {@link android.telecom.ConnectionService}, to ensure that only the system can bind to it. @deprecated {@link android.telecom.ConnectionService}s should require @@ -2832,15 +2971,6 @@ <permission android:name="android.permission.BIND_CONNECTION_SERVICE" android:protectionLevel="signature|privileged" /> - <!-- Must be required by a - android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService, - to ensure that only the system can bind to it. - @SystemApi @hide This is not a third-party API (intended for OEMs and system apps). - <p>Protection level: signature - --> - <permission android:name="android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE" - android:protectionLevel="signature" /> - <!-- Must be required by a {@link android.telecom.ConnectionService}, to ensure that only the system can bind to it. <p>Protection level: signature|privileged @@ -2869,6 +2999,16 @@ <permission android:name="android.permission.MANAGE_SENSORS" android:protectionLevel="signature" /> + <!-- Must be required by a DomainSelectionService to ensure that only the + system can bind to it. + <p>Protection level: signature + @SystemApi + @hide + @FlaggedApi("com.android.internal.telephony.flags.use_oem_domain_selection_service") + --> + <permission android:name="android.permission.BIND_DOMAIN_SELECTION_SERVICE" + android:protectionLevel="signature" /> + <!-- Must be required by an ImsService to ensure that only the system can bind to it. <p>Protection level: signature|privileged|vendorPrivileged @@ -2878,6 +3018,23 @@ <permission android:name="android.permission.BIND_IMS_SERVICE" android:protectionLevel="signature|privileged|vendorPrivileged" /> + <!-- Must be required by a SatelliteService to ensure that only the + system can bind to it. + <p>Protection level: signature|privileged|vendorPrivileged + @SystemApi + @hide + --> + <permission android:name="android.permission.BIND_SATELLITE_SERVICE" + android:protectionLevel="signature|privileged|vendorPrivileged" /> + + <!-- Must be required by a SatelliteGatewayService to ensure that only the + system can bind to it. + <p>Protection level: signature + @hide + --> + <permission android:name="android.permission.BIND_SATELLITE_GATEWAY_SERVICE" + android:protectionLevel="signature" /> + <!-- Must be required by a telephony data service to ensure that only the system can bind to it. <p>Protection level: signature @@ -2938,6 +3095,17 @@ <permission android:name="android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE" android:protectionLevel="internal|role" /> + <!-- Used to provide the Telecom framework with access to the last known call ID. + <p>Protection level: signature + @SystemApi + @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") + @hide + --> + <permission android:name="android.permission.ACCESS_LAST_KNOWN_CELL_ID" + android:protectionLevel="signature" + android:label="@string/permlab_accessLastKnownCellId" + android:description="@string/permdesc_accessLastKnownCellId"/> + <!-- ================================== --> <!-- Permissions for sdcard interaction --> <!-- ================================== --> @@ -3056,23 +3224,38 @@ types of interactions @hide --> <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" - android:protectionLevel="signature|installer|role" /> + android:protectionLevel="signature|installer|module|role" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <!-- Allows interaction across profiles in the same profile group. --> <permission android:name="android.permission.INTERACT_ACROSS_PROFILES" android:protectionLevel="signature|appop" /> + <!-- Allows applications to access profiles with ACCESS_HIDDEN_PROFILES user property + <p>Protection level: normal + @FlaggedApi("android.multiuser.enable_permission_to_access_hidden_profiles") --> + <permission android:name="android.permission.ACCESS_HIDDEN_PROFILES" + android:label="@string/permlab_accessHiddenProfile" + android:description="@string/permdesc_accessHiddenProfile" + android:protectionLevel="normal" /> + + <!-- @SystemApi @hide Allows privileged applications to get details about hidden profile + users. + @FlaggedApi("android.multiuser.flags.enable_permission_to_access_hidden_profiles") --> + <permission + android:name="android.permission.ACCESS_HIDDEN_PROFILES_FULL" + android:protectionLevel="signature|privileged" /> + + <!-- @SystemApi @hide Allows starting activities across profiles in the same profile group. --> + <permission android:name="android.permission.START_CROSS_PROFILE_ACTIVITIES" + android:protectionLevel="signature|role" /> + <!-- @SystemApi Allows configuring apps to have the INTERACT_ACROSS_PROFILES permission so that they can interact across profiles in the same profile group. @hide --> <permission android:name="android.permission.CONFIGURE_INTERACT_ACROSS_PROFILES" android:protectionLevel="signature|role" /> - <!-- @SystemApi @hide Allows starting activities across profiles in the same profile group. --> - <permission android:name="android.permission.START_CROSS_PROFILE_ACTIVITIES" - android:protectionLevel="signature|role" /> - <!-- @SystemApi @hide Allows an application to call APIs that allow it to query and manage users on the device. This permission is not available to third party applications. --> @@ -3446,11 +3629,18 @@ <!-- Allows an application to set policy related to <a href="https://www.threadgroup.org">Thread</a> network. - @FlaggedApi("com.android.net.thread.flags.thread_user_restriction_enabled") + @FlaggedApi("com.android.net.thread.platform.flags.thread_user_restriction_enabled") --> <permission android:name="android.permission.MANAGE_DEVICE_POLICY_THREAD_NETWORK" android:protectionLevel="internal|role" /> + <!-- Allows an application to set policy related to sending assist content to a + privileged app such as the Assistant app. + @FlaggedApi("android.app.admin.flags.assist_content_user_restriction_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_ASSIST_CONTENT" + android:protectionLevel="internal|role" /> + <!-- Allows an application to set policy related to windows. <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call APIs protected by this permission on users different to the calling user. @@ -3500,6 +3690,14 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING" android:protectionLevel="internal|role" /> + <!-- Allows an application to use audit logging API. + @hide + @SystemApi + @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIT_LOGGING" + android:protectionLevel="internal|role" /> + <!-- Allows an application to set policy related to system updates. <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call APIs protected by this permission on users different to the calling user. @@ -3507,7 +3705,7 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES" android:protectionLevel="internal|role" /> - <!-- Allows an application to query system updates. + <!-- Allows an application query system updates. <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call APIs protected by this permission on users different to the calling user. --> @@ -3603,6 +3801,14 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK" android:protectionLevel="internal|role" /> + <!-- Allows an application to query the device stolen state. + @FlaggedApi("android.app.admin.flags.device_theft_api_enabled") + @hide + @SystemApi + --> + <permission android:name="android.permission.QUERY_DEVICE_STOLEN_STATE" + android:protectionLevel="internal|role" /> + <!-- Allows an application to manage policy related to system apps. <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call APIs protected by this permission on users different to the calling user. @@ -3626,6 +3832,38 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_DEVICE_IDENTIFIERS" android:protectionLevel="internal|role" /> + <!-- Allows an application to manage policy related to content protection. + <p>Protection level: internal|role + @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_CONTENT_PROTECTION" + android:protectionLevel="internal|role" /> + + <!-- Allows an application to set policy related to subscriptions downloaded by an admin. + <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call + APIs protected by this permission on users different to the calling user. + @FlaggedApi("android.app.admin.flags.esim_management_enabled") --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_MANAGED_SUBSCRIPTIONS" + android:protectionLevel="internal|role" /> + + <!-- Allows an application to manage policy related to block package uninstallation. + @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL" + android:protectionLevel="internal|role" /> + + <!-- Allows an application to manage policy related to camera toggle. + @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_CAMERA_TOGGLE" + android:protectionLevel="internal|role" /> + + <!-- Allows an application to manage policy related to microphone toggle. + @FlaggedApi("android.app.admin.flags.dedicated_device_control_api_enabled") + --> + <permission android:name="android.permission.MANAGE_DEVICE_POLICY_MICROPHONE_TOGGLE" + android:protectionLevel="internal|role" /> + <!-- Allows an application to set device policies outside the current user that are critical for securing data within the current user. <p>Holding this permission allows the use of other held MANAGE_DEVICE_POLICY_* @@ -3650,6 +3888,14 @@ <permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL" android:protectionLevel="internal|role" /> + <!-- Allows an application to access EnhancedConfirmationManager. + @SystemApi + @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") + @hide This is not a third-party API (intended for OEMs and system apps). --> + <permission android:name="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" + android:protectionLevel="signature|installer" /> + <uses-permission android:name="android.permission.MANAGE_ENHANCED_CONFIRMATION_STATES" /> + <!-- @SystemApi @hide Allows an application to set a device owner on retail demo devices.--> <permission android:name="android.permission.PROVISION_DEMO_DEVICE" android:protectionLevel="signature|setup|knownSigner" @@ -3665,11 +3911,6 @@ <permission android:name="android.permission.FORCE_DEVICE_POLICY_MANAGER_LOGS" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to write to the security log buffer in logd. - @hide --> - <permission android:name="android.permission.WRITE_SECURITY_LOG" - android:protectionLevel="signature|privileged" /> - <!-- Allows an application to get full detailed information about recently running tasks, with full fidelity to the real state. @hide --> @@ -3701,6 +3942,18 @@ <permission android:name="android.permission.ACTIVITY_EMBEDDING" android:protectionLevel="signature|privileged" /> + <!-- Allows an application to embed any other apps in untrusted embedding mode without the need + for the embedded app to consent. + <p>For now, this permission is only granted to the Assistant application selected by + the user. + {@see https://developer.android.com/guide/topics/large-screens/activity-embedding#trust_model} + @SystemApi + @FlaggedApi("com.android.window.flags.untrusted_embedding_any_app_permission") + @hide + --> + <permission android:name="android.permission.EMBED_ANY_APP_IN_UNTRUSTED_MODE" + android:protectionLevel="internal|role" /> + <!-- Allows an application to start any activity, regardless of permission protection or exported state. @hide --> @@ -3747,13 +4000,15 @@ android:description="@string/permdesc_killBackgroundProcesses" android:protectionLevel="normal" /> - <!-- @deprecated Allows an application to call + <!-- Allows an application to call {@link android.app.ActivityManager#killBackgroundProcesses}. <p>As of Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the {@link android.app.ActivityManager#killBackgroundProcesses} is no longer available to third party applications. For backwards compatibility, the background processes of the - caller's own package will still be killed when calling this API, meanwhile this permission - is not required anymore in this case. + caller's own package will still be killed when calling this API. If the caller has + the system permission {@code KILL_ALL_BACKGROUND_PROCESSES}, other processes will be + killed too. + <p>Protection level: normal --> <permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" @@ -3862,7 +4117,9 @@ <p>Protection level: normal --> <permission android:name="android.permission.REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND" - android:protectionLevel="normal"/> + android:label="@string/permlab_startForegroundServicesFromBackground" + android:description="@string/permdesc_startForegroundServicesFromBackground" + android:protectionLevel="normal"/> <!-- Allows a companion app to use data in the background. <p>Protection level: normal @@ -3878,6 +4135,8 @@ <p>Protection level: normal --> <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_WATCH" + android:label="@string/permlab_companionProfileWatch" + android:description="@string/permdesc_companionProfileWatch" android:protectionLevel="normal" /> <!-- Allows app to request to be associated with a device via @@ -3897,8 +4156,7 @@ <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING" android:protectionLevel="signature|privileged" /> - <!-- Allows application to request to be associated with a virtual device associated to a - nearby device capable of rendering an entire OS + <!-- Allows application to request to stream content from an Android host to a nearby device ({@link android.companion.AssociationRequest#DEVICE_PROFILE_NEARBY_DEVICE_STREAMING}) by {@link android.companion.CompanionDeviceManager}. <p>Not for use by third-party applications. @@ -3916,11 +4174,11 @@ android:protectionLevel="internal|role" /> <!-- Allows application to request to be associated with a computer to share functionality - and/or data with other devices, such as notifications, photos and media - ({@link android.companion.AssociationRequest#DEVICE_PROFILE_COMPUTER}) - by {@link android.companion.CompanionDeviceManager}. - <p>Not for use by third-party applications. - --> + and/or data with other devices, such as notifications, photos and media + ({@link android.companion.AssociationRequest#DEVICE_PROFILE_COMPUTER}) + by {@link android.companion.CompanionDeviceManager}. + <p>Not for use by third-party applications. + --> <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_COMPUTER" android:protectionLevel="signature|privileged" /> @@ -3953,6 +4211,8 @@ <!-- Allows an app to prevent non-system-overlay windows from being drawn on top of it --> <permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" + android:label="@string/permlab_hideOverlayWindows" + android:description="@string/permdesc_hideOverlayWindows" android:protectionLevel="normal" /> <!-- ================================== --> @@ -3976,8 +4236,7 @@ android:description="@string/permdesc_setWallpaperHints" android:protectionLevel="normal" /> - <!-- Allow the app to read the system wallpaper image without - holding the READ_EXTERNAL_STORAGE permission. + <!-- Allow the app to read the system and lock wallpaper images. <p>Not for use by third-party applications. @hide @SystemApi @@ -3988,6 +4247,7 @@ <!-- Allow apps to always update wallpaper by sending data. @SystemApi @hide + @FlaggedApi("com.android.window.flags.always_update_wallpaper_permission") --> <permission android:name="android.permission.ALWAYS_UPDATE_WALLPAPER" android:protectionLevel="internal|role" /> @@ -4151,11 +4411,6 @@ <permission android:name="android.permission.WRITE_DEVICE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> - <!-- @SystemApi @hide Allows an application to read config settings. - <p>Not for use by third-party applications. --> - <permission android:name="android.permission.READ_DEVICE_CONFIG" - android:protectionLevel="signature|preinstalled" /> - <!-- @SystemApi @TestApi @hide Allows an application to modify only allowlisted settings. <p>Not for use by third-party applications. --> <permission android:name="android.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG" @@ -4166,6 +4421,11 @@ <permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> + <!-- @SystemApi @hide Allows an application to read config settings. + <p>Not for use by third-party applications. --> + <permission android:name="android.permission.READ_DEVICE_CONFIG" + android:protectionLevel="signature|preinstalled" /> + <!-- @SystemApi @hide Allows applications like settings to read system-owned application-specific locale configs. <p>Not for use by third-party applications. --> @@ -4177,7 +4437,7 @@ <permission android:name="android.permission.SET_APP_SPECIFIC_LOCALECONFIG" android:protectionLevel="signature" /> - <!-- @hide Allows an application to monitor {@link android.provider.Settings.Config} access. + <!-- @SystemApi @hide Allows an application to monitor {@link android.provider.Settings.Config} access. <p>Not for use by third-party applications. --> <permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS" android:protectionLevel="signature"/> @@ -4352,7 +4612,8 @@ <!-- Allows an application to query the current time zone rules state on device. - @SystemApi @hide --> + @SystemApi @hide + @deprecated Vestigial permission declaration. No longer used. --> <permission android:name="android.permission.QUERY_TIME_ZONE_RULES" android:protectionLevel="signature|privileged" /> @@ -4361,7 +4622,8 @@ <p>An application requesting this permission is responsible for verifying the source and integrity of the update before passing it off to the installer components. - @SystemApi @hide --> + @SystemApi @hide + @deprecated Vestigial permission declaration. No longer used. --> <permission android:name="android.permission.UPDATE_TIME_ZONE_RULES" android:protectionLevel="signature|privileged" /> @@ -4415,6 +4677,45 @@ <permission android:name="android.permission.REQUEST_UNIQUE_ID_ATTESTATION" android:protectionLevel="signature" /> + <!-- Allows an application to get enabled credential manager providers. + @hide --> + <permission android:name="android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS" + android:protectionLevel="signature|privileged" /> + + <!-- Allows a system application to be registered with credential manager without + having to be enabled by the user. + @hide @SystemApi --> + <permission android:name="android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE" + android:protectionLevel="signature|privileged" /> + + <!-- Allows specifying candidate credential providers to be queried in Credential Manager + get flows, or to be preferred as a default in the Credential Manager create flows. + <p>Protection level: normal --> + <permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS" + android:protectionLevel="normal" /> + + <!-- Allows a browser to invoke credential manager APIs on behalf of another RP. + <p>Protection level: normal --> + <permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ORIGIN" + android:protectionLevel="normal" /> + + <!-- Allows a browser to invoke the set of query apis to get metadata about credential + candidates prepared during the CredentialManager.prepareGetCredential API. + <p>Protection level: normal --> + <permission android:name="android.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS" + android:protectionLevel="normal" /> + + <!-- Allows permission to use Credential Manager UI for providing and saving credentials + @hide --> + <permission android:name="android.permission.LAUNCH_CREDENTIAL_SELECTOR" + android:protectionLevel="signature" /> + + <!-- Allows an application to be able to store and retrieve credentials from a remote + device. + <p>Protection level: signature|privileged|role --> + <permission android:name="android.permission.PROVIDE_REMOTE_CREDENTIALS" + android:protectionLevel="signature|privileged|role" /> + <!-- ========================================= --> <!-- Permissions for special development tools --> <!-- ========================================= --> @@ -4442,15 +4743,17 @@ <permission android:name="android.permission.READ_LOGS" android:protectionLevel="signature|privileged|development" /> - <!-- Allows an application to access the data in Dropbox--> - <permission android:name="android.permission.READ_DROPBOX_DATA" - android:protectionLevel="signature|privileged|development" /> - <!-- Configure an application for debugging. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_DEBUG_APP" android:protectionLevel="signature|privileged|development" /> + <!-- Allows an application to access the data in Dropbox. + <p>Not for use by third-party applications. + @FlaggedApi("com.android.server.feature.flags.enable_read_dropbox_permission") --> + <permission android:name="android.permission.READ_DROPBOX_DATA" + android:protectionLevel="signature|privileged|development" /> + <!-- Allows an application to set the maximum number of (not needed) application processes that can be running. <p>Not for use by third-party applications. --> @@ -4585,7 +4888,7 @@ <permission android:name="android.permission.MANAGE_APP_OPS_RESTRICTIONS" android:protectionLevel="signature|installer" /> - <!-- Allows an application to update the user app op modes. + <!-- @TestApi Allows an application to update the user app op modes. Not for use by third party apps. @hide --> <permission android:name="android.permission.MANAGE_APP_OPS_MODES" @@ -4666,6 +4969,13 @@ <permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" android:protectionLevel="signature" /> + <!-- @FlaggedApi("com.android.server.accessibility.motion_event_observing") + @hide + @TestApi + Allows an accessibility service to observe motion events without consuming them. --> + <permission android:name="android.permission.ACCESSIBILITY_MOTION_EVENT_OBSERVING" + android:protectionLevel="signature" /> + <!-- @hide Allows an application to collect frame statistics --> <permission android:name="android.permission.FRAME_STATS" android:protectionLevel="signature" /> @@ -4713,9 +5023,9 @@ android:protectionLevel="signature|recents" /> <!-- @SystemApi Allows an application to set the system audio caption and its UI - enabled state. - <p>Not for use by third-party applications. - @hide --> + enabled state. + <p>Not for use by third-party applications. + @hide --> <permission android:name="android.permission.SET_SYSTEM_AUDIO_CAPTION" android:protectionLevel="signature|role" /> @@ -4734,7 +5044,8 @@ android:protectionLevel="signature" /> <!-- Allows access to Test APIs defined in {@link android.view.inputmethod.InputMethodManager}. - @hide --> + @hide + @TestApi --> <permission android:name="android.permission.TEST_INPUT_METHOD" android:protectionLevel="signature" /> @@ -4790,7 +5101,7 @@ <p>Protection level: signature --> <permission android:name="android.permission.BIND_NFC_SERVICE" - android:protectionLevel="signature" /> + android:protectionLevel="signature|module" /> <!-- Must be required by a {@link android.service.quickaccesswallet.QuickAccessWalletService} to ensure that only the system can bind to it. @@ -4846,32 +5157,6 @@ android:protectionLevel="signature" /> <uses-permission android:name="android.permission.BIND_ROTATION_RESOLVER_SERVICE" /> - <!-- @SystemApi Allows an application to access ambient context service. - @hide <p>Not for use by third-party applications.</p> --> - <permission android:name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT" - android:protectionLevel="signature|privileged|role"/> - - <!-- @SystemApi Required by a AmbientContextEventDetectionService - to ensure that only the service with this permission can bind to it. - @hide <p>Not for use by third-party applications.</p> --> - <permission android:name="android.permission.BIND_AMBIENT_CONTEXT_DETECTION_SERVICE" - android:protectionLevel="signature"/> - - <!-- @SystemApi Required by a WearableSensingService to - ensure that only the caller with this permission can bind to it. - <p> Protection level: signature - @hide - --> - <permission android:name="android.permission.BIND_WEARABLE_SENSING_SERVICE" - android:protectionLevel="signature" /> - - <!-- @SystemApi Allows an app to manage the wearable sensing service. - <p>Protection level: signature|privileged - @hide - --> - <permission android:name="android.permission.MANAGE_WEARABLE_SENSING_SERVICE" - android:protectionLevel="signature|privileged" /> - <!-- Must be required by a {@link android.net.VpnService}, to ensure that only the system can bind to it. <p>Protection level: signature @@ -4886,14 +5171,14 @@ <permission android:name="android.permission.BIND_WALLPAPER" android:protectionLevel="signature|privileged" /> + <!-- Must be required by a game service to ensure that only the system can bind to it. <p>Protection level: signature - @SystemApi @hide --> <permission android:name="android.permission.BIND_GAME_SERVICE" - android:protectionLevel="signature" /> + android:protectionLevel="signature" /> <!-- Must be required by a {@link android.service.voice.VoiceInteractionService}, to ensure that only the system can bind to it. @@ -4910,15 +5195,6 @@ <permission android:name="android.permission.BIND_HOTWORD_DETECTION_SERVICE" android:protectionLevel="signature" /> - <!-- @SystemApi Must be required by a {@link android.service.voice.visualQueryDetection}, - to ensure that only the system can bind to it. - <p>Protection level: signature - @hide This is not a third-party API (intended for OEMs and system apps). - --> - <permission android:name="android.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE" - android:protectionLevel="signature" /> - - <!-- @SystemApi Allows an application to manage hotword detection and visual query detection on the device. <p>Protection level: internal|preinstalled @@ -4927,19 +5203,20 @@ <permission android:name="android.permission.MANAGE_HOTWORD_DETECTION" android:protectionLevel="internal|preinstalled" /> + <!-- @SystemApi Must be required by a {@link android.service.voice.VisualQueryDetectionService}, + to ensure that only the system can bind to it. + <p>Protection level: signature + @hide This is not a third-party API (intended for OEMs and system apps). + --> + <permission android:name="android.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE" + android:protectionLevel="signature" /> + <!-- Allows an application to subscribe to keyguard locked (i.e., showing) state. <p>Protection level: signature|role <p>Intended for use by ROLE_ASSISTANT and signature apps only. --> <permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE" - android:protectionLevel="signature|role"/> - - <!-- Must be required by a {@link android.service.credentials.CredentialProviderService}, - to ensure that only the system can bind to it. - <p>Protection level: signature - --> - <permission android:name="android.permission.BIND_CREDENTIAL_PROVIDER_SERVICE" - android:protectionLevel="signature" /> + android:protectionLevel="signature|module|role"/> <!-- Must be required by a {@link android.service.autofill.AutofillService}, to ensure that only the system can bind to it. @@ -4957,12 +5234,19 @@ <permission android:name="android.permission.BIND_FIELD_CLASSIFICATION_SERVICE" android:protectionLevel="signature" /> - <!-- Alternative version of android.permission.BIND_AUTOFILL_FIELD_CLASSIFICATION_SERVICE. - This permission was renamed during the O previews but it was supported on the final O - release, so we need to carry it over. + <!-- Must be required by a CredentialProviderService to ensure that only the + system can bind to it. <p>Protection level: signature - @hide - --> + --> + <permission android:name="android.permission.BIND_CREDENTIAL_PROVIDER_SERVICE" + android:protectionLevel="signature" /> + + <!-- Alternative version of android.permission.BIND_AUTOFILL_FIELD_CLASSIFICATION_SERVICE. + This permission was renamed during the O previews but it was supported on the final O + release, so we need to carry it over. + <p>Protection level: signature + @hide + --> <permission android:name="android.permission.BIND_AUTOFILL" android:protectionLevel="signature" /> @@ -4998,9 +5282,9 @@ android:protectionLevel="signature" /> <!-- Must be required by a android.service.selectiontoolbar.SelectionToolbarRenderService, - to ensure that only the system can bind to it. - @hide This is not a third-party API (intended for OEMs and system apps). - <p>Protection level: signature + to ensure that only the system can bind to it. + @hide This is not a third-party API (intended for OEMs and system apps). + <p>Protection level: signature --> <permission android:name="android.permission.BIND_SELECTION_TOOLBAR_RENDER_SERVICE" android:protectionLevel="signature" /> @@ -5036,6 +5320,16 @@ <permission android:name="android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE" android:protectionLevel="signature" /> + <!-- Must be required by a + android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService, + to ensure that only the system can bind to it. + @SystemApi @hide This is not a third-party API (intended for OEMs and system apps). + <p>Protection level: signature + --> + <permission android:name="android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE" + android:protectionLevel="signature" /> + + <!-- Must be declared by a android.service.musicrecognition.MusicRecognitionService, to ensure that only the system can bind to it. @SystemApi @hide This is not a third-party API (intended for OEMs and system apps). @@ -5058,7 +5352,9 @@ this permission, it must hold the permission and be the active VoiceInteractionService in the system. {@see Settings.Secure.VOICE_INTERACTION_SERVICE} - @hide --> + @hide @SystemApi Intended for OEM and system apps. + <p>Protection level: signature|privileged + --> <permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES" android:protectionLevel="signature|privileged" /> @@ -5067,7 +5363,9 @@ sound models at any time. This permission should be reserved for system enrollment applications detected by {@link android.hardware.soundtrigger.KeyphraseEnrollmentInfo} only. - @hide <p>Not for use by third-party applications.</p> --> + @hide @SystemApi Intended for OEM and system apps. + <p>Protection level: signature|privileged + --> <permission android:name="android.permission.KEYPHRASE_ENROLLMENT_APPLICATION" android:protectionLevel="signature|privileged" /> @@ -5077,6 +5375,14 @@ <permission android:name="android.permission.BIND_REMOTE_DISPLAY" android:protectionLevel="signature" /> + <!-- Must be required by a android.media.tv.ad.TvAdService to ensure that only the system can + bind to it. + <p>Protection level: signature|privileged + @FlaggedApi("android.media.tv.flags.enable_ad_service_fw") + --> + <permission android:name="android.permission.BIND_TV_AD_SERVICE" + android:protectionLevel="signature|privileged" /> + <!-- Must be required by a {@link android.media.tv.TvInputService} to ensure that only the system can bind to it. <p>Protection level: signature|privileged @@ -5100,15 +5406,6 @@ <permission android:name="android.permission.BIND_TV_REMOTE_SERVICE" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows TV input apps and TV apps to use TIS extension interfaces for - domain-specific features. - <p>Protection level: signature|privileged|vendorPrivileged - <p>Not for use by third-party applications. - @hide - --> - <permission android:name="android.permission.TIS_EXTENSION_INTERFACE" - android:protectionLevel="signature|privileged|vendorPrivileged" /> - <!-- @SystemApi Must be required for a virtual remote controller for TV. <p>Protection level: signature|privileged @@ -5152,7 +5449,7 @@ <!-- @SystemApi This permission is required by Media Resource Manager Service when system services create MediaCodecs on behalf of other processes and apps. - <p>Protection level: signature + <p>Protection level: signature|privileged|vendorPrivileged <p>Not for use by third-party applications. @hide --> <permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID" @@ -5226,19 +5523,6 @@ <permission android:name="android.permission.SET_KEYBOARD_LAYOUT" android:protectionLevel="signature" /> - <!-- Allows low-level access for re-mapping modifier keys. - <p>Not for use by third-party applications. - @hide - @TestApi --> - <permission android:name="android.permission.REMAP_MODIFIER_KEYS" - android:protectionLevel="signature" /> - - <!-- Allows low-level access for monitoring keyboard backlight changes. - <p>Not for use by third-party applications. - @hide --> - <permission android:name="android.permission.MONITOR_KEYBOARD_BACKLIGHT" - android:protectionLevel="signature" /> - <!-- Allows an app to schedule a prioritized alarm that can be used to perform background work even when the device is in doze. <p>Not for use by third-party applications. @@ -5249,27 +5533,53 @@ android:protectionLevel="signature|privileged"/> <!-- Allows applications to use exact alarm APIs. - <p>Exact alarms should only be used for user-facing features. - For more details, see <a - href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission"> - Exact alarm permission</a>. - <p>Apps who hold this permission and target API level 31 or above, always stay in the + <p>This is a special access permission that can be revoked by the system or the user. + It should only be used to enable <b>user-facing features</b> that require exact alarms. + For more details, please go through the associated + <a href="{@docRoot}training/scheduling/alarms#exact">developer docs</a>. + <p>Apps need to target API {@link android.os.Build.VERSION_CODES#S} or above to be able to + request this permission. Note that apps targeting lower API levels do not need this + permission to use exact alarm APIs. + <p>Apps that hold this permission and target API + {@link android.os.Build.VERSION_CODES#TIRAMISU} and below always stay in the {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_WORKING_SET WORKING_SET} or lower standby bucket. - Applications targeting API level 30 or below do not need this permission to use - exact alarm APIs. + <p>If your app relies on exact alarms for core functionality, it can instead request + {@link android.Manifest.permission#USE_EXACT_ALARM} once it targets API + {@link android.os.Build.VERSION_CODES#TIRAMISU}. All apps using exact alarms for secondary + features (which should still be user facing) should continue using this permission. + <p>Protection level: signature|privileged|appop --> <permission android:name="android.permission.SCHEDULE_EXACT_ALARM" + android:label="@string/permlab_schedule_exact_alarm" + android:description="@string/permdesc_schedule_exact_alarm" android:protectionLevel="signature|privileged|appop"/> - <!-- Allows apps to use exact alarms just like with SCHEDULE_EXACT_ALARM but without needing - to request this permission from the user. - <p><b>This is only for apps that rely on exact alarms for their core functionality.</b> - App stores may enforce policies to audit and review the use of this permission. Any app that - requests this but is found to not require exact alarms for its primary function may be - removed from the app store. + <!-- Allows apps to use exact alarms just like with {@link + android.Manifest.permission#SCHEDULE_EXACT_ALARM} but without needing to request this + permission from the user. + <p><b> This is only intended for use by apps that rely on exact alarms for their core + functionality.</b> You should continue using {@code SCHEDULE_EXACT_ALARM} if your app needs + exact alarms for a secondary feature that users may or may not use within your app. + <p> Keep in mind that this is a powerful permission and app stores may enforce policies to + audit and review the use of this permission. Such audits may involve removal from the app + store if the app is found to be misusing this permission. + <p> Apps need to target API {@link android.os.Build.VERSION_CODES#TIRAMISU} or above to be + able to request this permission. Note that only one of {@code USE_EXACT_ALARM} or + {@code SCHEDULE_EXACT_ALARM} should be requested on a device. If your app is already using + {@code SCHEDULE_EXACT_ALARM} on older SDKs but needs {@code USE_EXACT_ALARM} on SDK 33 and + above, then {@code SCHEDULE_EXACT_ALARM} should be declared with a max-sdk attribute, like: + <pre> + <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" + 	 android:maxSdkVersion="32" /> + </pre> + <p>Apps that hold this permission, always stay in the + {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_WORKING_SET WORKING_SET} or + lower standby bucket. --> <permission android:name="android.permission.USE_EXACT_ALARM" + android:label="@string/permlab_use_exact_alarm" + android:description="@string/permdesc_use_exact_alarm" android:protectionLevel="normal"/> <!-- Allows an application to query tablet mode state and monitor changes @@ -5360,9 +5670,10 @@ of a session based install. <p>Not for use by third-party applications. @hide + @FlaggedApi("android.content.pm.get_resolved_apk_path") --> <permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS" - android:protectionLevel="signature|installer" /> + android:protectionLevel="signature|installer" /> <uses-permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS" /> <!-- Allows an application to use System Data Loaders. @@ -5450,7 +5761,7 @@ <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" android:protectionLevel="signature|privileged|role" /> - <!-- @SystemApi Allows an application to grant specific permissions. + <!-- @SystemApi @TestApi iAllows an application to grant specific permissions. @hide --> <permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" android:protectionLevel="signature|installer|verifier" /> @@ -5472,11 +5783,11 @@ <permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" android:protectionLevel="signature|installer|verifier" /> - <!-- @TestApi Allows an application to revoke the POST_NOTIFICATIONS permission from an app - without killing the app. Only granted to the shell. - @hide --> + <!-- @TestApi Allows an application to revoke the POST_NOTIFICATIONS permission from an app + without killing the app. Only granted to the shell. + @hide --> <permission android:name="android.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL" - android:protectionLevel="signature" /> + android:protectionLevel="signature" /> <!-- @SystemApi Allows the system to read runtime permission state. @hide --> @@ -5490,7 +5801,7 @@ <permission android:name="android.permission.RESTORE_RUNTIME_PERMISSIONS" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to change policy_fixed permissions. + <!-- @SystemApi @TestApi Allows an application to change policy_fixed permissions. @hide --> <permission android:name="android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY" android:protectionLevel="signature|installer" /> @@ -5501,7 +5812,7 @@ android:protectionLevel="signature" /> <!-- @SystemApi Allows an application to allowlist restricted permissions - on any of the whitelists. + on any of the allowlists. @hide --> <permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" android:protectionLevel="signature|installer" /> @@ -5524,7 +5835,8 @@ <!-- @SystemApi Allows an application to manage the holders of a role. @hide --> <permission android:name="android.permission.MANAGE_ROLE_HOLDERS" - android:protectionLevel="signature|installer" /> + android:protectionLevel="signature|installer|module" /> + <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" /> <!-- @SystemApi Allows an application to manage the holders of roles associated with default applications. @@ -5544,28 +5856,41 @@ <!-- @SystemApi Allows an application to observe role holder changes. @hide --> <permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" - android:protectionLevel="signature|installer" /> + android:protectionLevel="signature|installer|module" /> <!-- Allows an application to manage the companion devices. @hide --> <permission android:name="android.permission.MANAGE_COMPANION_DEVICES" - android:protectionLevel="signature|role|module" /> + android:protectionLevel="module|signature|role" /> <!-- Allows an application to subscribe to notifications about the presence status change of their associated companion device --> <permission android:name="android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE" + android:label="@string/permlab_observeCompanionDevicePresence" + android:description="@string/permdesc_observeCompanionDevicePresence" android:protectionLevel="normal" /> + <!-- Allows an application to subscribe to notifications about the nearby devices' presence + status change base on the UUIDs. + <p>Not for use by third-party applications.</p> + @FlaggedApi("android.companion.flags.device_presence") + --> + <permission android:name="android.permission.REQUEST_OBSERVE_DEVICE_UUID_PRESENCE" + android:protectionLevel="signature|privileged" /> + <!-- Allows an application to deliver companion messages to system --> <permission android:name="android.permission.DELIVER_COMPANION_MESSAGES" + android:label="@string/permlab_deliverCompanionMessages" + android:description="@string/permdesc_deliverCompanionMessages" android:protectionLevel="normal" /> - <!-- @SystemApi Allows an application to send and receive messages via CDM transports. - @hide --> + <!-- @hide @FlaggedApi("android.companion.flags.companion_transport_apis") + Allows an application to send and receive messages via CDM transports. + --> <permission android:name="android.permission.USE_COMPANION_TRANSPORTS" - android:protectionLevel="signature|module" /> + android:protectionLevel="signature" /> <!-- Allows an application to create new companion device associations. @SystemApi @@ -5588,7 +5913,7 @@ <permission android:name="android.permission.ROTATE_SURFACE_FLINGER" android:protectionLevel="signature|recents" /> - <!-- @SystemApi Allows an application to provide hints to SurfaceFlinger that can influence + <!-- Allows an application to provide hints to SurfaceFlinger that can influence its wakes up time to compose the next frame. This is a subset of the capabilities granted by {@link #ACCESS_SURFACE_FLINGER}. <p>Not for use by third-party applications. @@ -5605,6 +5930,13 @@ <permission android:name="android.permission.READ_FRAME_BUFFER" android:protectionLevel="signature|recents" /> + <!-- Allows an application to change the touch mode state. + Without this permission, an app can only change the touch mode + if it currently has focus. + @hide --> + <permission android:name="android.permission.MODIFY_TOUCH_MODE_STATE" + android:protectionLevel="signature" /> + <!-- Allows an application to use InputFlinger's low level features. @hide --> <permission android:name="android.permission.ACCESS_INPUT_FLINGER" @@ -5617,12 +5949,10 @@ <permission android:name="android.permission.DISABLE_INPUT_DEVICE" android:protectionLevel="signature" /> - <!-- Allows an application to configure and connect to Wifi displays - @hide - @SystemApi --> + <!-- Allows an application to configure and connect to Wifi displays --> <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" - android:protectionLevel="signature|knownSigner" - android:knownCerts="@array/wifi_known_signers" /> + android:protectionLevel="signature|knownSigner" + android:knownCerts="@array/wifi_known_signers" /> <!-- Allows an application to control low-level features of Wifi displays such as opening an RTSP socket. This permission should only be used @@ -5657,7 +5987,7 @@ <permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" android:protectionLevel="signature|privileged" /> - <!-- Allows an application to collect usage infomation about brightness slider changes. + <!-- Allows an application to collect usage information about brightness slider changes. <p>Not for use by third-party applications.</p> @hide @SystemApi @@ -5802,21 +6132,21 @@ <permission android:name="android.permission.MODIFY_AUDIO_ROUTING" android:protectionLevel="signature|privileged|role" /> - <!-- @SystemApi Allows an application to access the uplink and downlink audio of an ongoing - call. - <p>Not for use by third-party applications.</p> - @hide --> - <permission android:name="android.permission.CALL_AUDIO_INTERCEPTION" - android:protectionLevel="signature|privileged|role" /> - <!--@SystemApi Allows an application to modify system audio settings that shouldn't be - controllable by external apps, such as volume settings or volume behaviors for audio - devices, regardless of their connection status. - <p>Not for use by third-party applications. - @hide --> + controllable by external apps, such as volume settings or volume behaviors for audio + devices, regardless of their connection status. + <p>Not for use by third-party applications. + @hide --> <permission android:name="android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows an application to access the uplink and downlink audio of an ongoing + call. + <p>Not for use by third-party applications.</p> + @hide --> + <permission android:name="android.permission.CALL_AUDIO_INTERCEPTION" + android:protectionLevel="signature|privileged|role" /> + <!-- @TestApi Allows an application to query audio related state. @hide --> <permission android:name="android.permission.QUERY_AUDIO_STATE" @@ -5862,9 +6192,9 @@ android:protectionLevel="signature|privileged" /> <!-- Allows an application to control the routing of media apps. - <p>Only for use by role COMPANION_DEVICE_WATCH</p> - @FlaggedApi("com.android.media.flags.enable_privileged_routing_for_media_routing_control") - --> + <p>Only for use by role COMPANION_DEVICE_WATCH</p> + @FlaggedApi("com.android.media.flags.enable_privileged_routing_for_media_routing_control") + --> <permission android:name="android.permission.MEDIA_ROUTING_CONTROL" android:protectionLevel="signature|appop" /> @@ -5922,7 +6252,7 @@ <!-- @hide @SystemApi Allows an application to manage Low Power Standby settings. <p>Not for use by third-party applications. --> <permission android:name="android.permission.MANAGE_LOW_POWER_STANDBY" - android:protectionLevel="signature|privileged" /> + android:protectionLevel="signature|privileged" /> <!-- @hide @SystemApi Allows an application to request ports to remain open during Low Power Standby. @@ -5986,6 +6316,7 @@ <p>Not for use by third-party applications. --> <permission android:name="android.permission.CALL_PRIVILEGED" android:protectionLevel="signature|privileged" /> + <uses-permission android:name="android.permission.CALL_PRIVILEGED" /> <!-- @SystemApi Allows an application to perform CDMA OTA provisioning @hide --> <permission android:name="android.permission.PERFORM_CDMA_PROVISIONING" @@ -6052,8 +6383,7 @@ <permission android:name="android.permission.CHANGE_APP_IDLE_STATE" android:protectionLevel="signature|privileged" /> - <!-- @hide @TestApi @SystemApi Allows an application to change the estimated launch time - of an app. + <!-- @hide @SystemApi Allows an application to change the estimated launch time of an app. <p>Not for use by third-party applications. --> <permission android:name="android.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE" android:protectionLevel="signature|privileged" /> @@ -6113,11 +6443,6 @@ <permission android:name="android.permission.RECOVER_KEYSTORE" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows application to verify lockscreen credentials provided by a remote device. - @hide --> - <permission android:name="android.permission.CHECK_REMOTE_LOCKSCREEN" - android:protectionLevel="signature|privileged" /> - <!-- Allows a package to launch the secure full-backup confirmation UI. ONLY the system process may hold this permission. @hide --> @@ -6215,8 +6540,8 @@ <permission android:name="android.permission.SET_WALLPAPER_COMPONENT" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows applications to set wallpaper dim amount. - @hide --> + <!-- @SystemApi Allows applications to set the wallpaper dim amount. + @hide. --> <permission android:name="android.permission.SET_WALLPAPER_DIM_AMOUNT" android:protectionLevel="signature|privileged" /> @@ -6416,6 +6741,11 @@ <permission android:name="android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS" android:protectionLevel="signature"/> + <!-- @SystemApi Allows application to verify lockscreen credentials provided by a remote device. + @hide --> + <permission android:name="android.permission.CHECK_REMOTE_LOCKSCREEN" + android:protectionLevel="signature|privileged" /> + <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide --> <permission android:name="android.permission.MANAGE_FINGERPRINT" android:protectionLevel="signature|privileged" /> @@ -6444,7 +6774,15 @@ <!-- Allows the system to control the BiometricDialog (SystemUI). Reserved for the system. @hide --> <permission android:name="android.permission.MANAGE_BIOMETRIC_DIALOG" - android:protectionLevel="signature" /> + android:protectionLevel="signature" /> + + <!-- Allows an application to set the advanced features on BiometricDialog (SystemUI), including + logo, logo description. + <p>Not for use by third-party applications. + @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") + --> + <permission android:name="android.permission.SET_BIOMETRIC_DIALOG_ADVANCED" + android:protectionLevel="signature|privileged" /> <!-- Allows an application to control keyguard. Only allowed for system processes. @hide --> @@ -6579,6 +6917,13 @@ <permission android:name="android.permission.MANAGE_MEDIA_PROJECTION" android:protectionLevel="signature" /> + <!-- @hide @TestApi Allows an application to record sensitive content during media + projection. This is intended for on device screen recording system app. + @FlaggedApi("android.permission.flags.sensitive_notification_app_protection") --> + <permission android:name="android.permission.RECORD_SENSITIVE_CONTENT" + android:protectionLevel="signature" + android:featureFlag="android.permission.flags.sensitive_notification_app_protection"/> + <!-- @SystemApi Allows an application to read install sessions @hide This is not a third-party API (intended for system apps). --> <permission android:name="android.permission.READ_INSTALL_SESSIONS" @@ -6755,12 +7100,16 @@ <!-- Allows the holder to read blocked numbers. See {@link android.provider.BlockedNumberContract}. + @SystemApi + @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @hide --> <permission android:name="android.permission.READ_BLOCKED_NUMBERS" android:protectionLevel="signature" /> <!-- Allows the holder to write blocked numbers. See {@link android.provider.BlockedNumberContract}. + @SystemApi + @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @hide --> <permission android:name="android.permission.WRITE_BLOCKED_NUMBERS" android:protectionLevel="signature" /> @@ -6819,6 +7168,11 @@ <permission android:name="android.permission.MANAGE_ROTATION_RESOLVER" android:protectionLevel="signature"/> + <!-- @SystemApi Allows an application to manage the cloudsearch service. + @hide <p>Not for use by third-party applications.</p> --> + <permission android:name="android.permission.MANAGE_CLOUDSEARCH" + android:protectionLevel="signature|privileged|role" /> + <!-- @SystemApi Allows an application to manage the music recognition service. @hide <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.MANAGE_MUSIC_RECOGNITION" @@ -6829,10 +7183,10 @@ <permission android:name="android.permission.MANAGE_SPEECH_RECOGNITION" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to manage the content suggestions service. + <!-- @SystemApi Allows an application to interact with the content suggestions service. @hide <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.MANAGE_CONTENT_SUGGESTIONS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|role" /> <!-- @SystemApi Allows an application to manage the app predictions service. @hide <p>Not for use by third-party applications.</p> --> @@ -6850,21 +7204,24 @@ android:protectionLevel="signature" /> <!-- @SystemApi Allows an application to access the smartspace service as a client. + @FlaggedApi(android.app.smartspace.flags.Flags.FLAG_ACCESS_SMARTSPACE) @hide <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.ACCESS_SMARTSPACE" android:protectionLevel="signature|privileged|development" /> + <!-- @SystemApi Allows an application to access the contextual search + service as a client. + @hide <p>Not for use by third-party applications.</p> --> + <permission android:name="android.permission.ACCESS_CONTEXTUAL_SEARCH" + android:protectionLevel="signature|privileged" + android:featureFlag="android.app.contextualsearch.flags.enable_service"/> + <!-- @SystemApi Allows an application to manage the wallpaper effects - generation service. - @hide <p>Not for use by third-party applications.</p> --> + generation service. + @hide <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to manage the cloudsearch service. - @hide <p>Not for use by third-party applications.</p> --> - <permission android:name="android.permission.MANAGE_CLOUDSEARCH" - android:protectionLevel="signature|privileged|role" /> - <!-- Allows an app to set the theme overlay in /vendor/overlay being used. @hide <p>Not for use by third-party applications.</p> --> @@ -6890,6 +7247,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" + android:description="@string/permdesc_foregroundServiceCamera" + android:label="@string/permlab_foregroundServiceCamera" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6897,6 +7256,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" + android:description="@string/permdesc_foregroundServiceConnectedDevice" + android:label="@string/permlab_foregroundServiceConnectedDevice" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6904,6 +7265,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" + android:description="@string/permdesc_foregroundServiceDataSync" + android:label="@string/permlab_foregroundServiceDataSync" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6911,6 +7274,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" + android:description="@string/permdesc_foregroundServiceLocation" + android:label="@string/permlab_foregroundServiceLocation" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6918,6 +7283,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" + android:description="@string/permdesc_foregroundServiceMediaPlayback" + android:label="@string/permlab_foregroundServiceMediaPlayback" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6925,6 +7292,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" + android:description="@string/permdesc_foregroundServiceMediaProjection" + android:label="@string/permlab_foregroundServiceMediaProjection" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6932,6 +7301,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" + android:description="@string/permdesc_foregroundServiceMicrophone" + android:label="@string/permlab_foregroundServiceMicrophone" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6939,6 +7310,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" + android:description="@string/permdesc_foregroundServicePhoneCall" + android:label="@string/permlab_foregroundServicePhoneCall" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6946,6 +7319,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_HEALTH" + android:description="@string/permdesc_foregroundServiceHealth" + android:label="@string/permlab_foregroundServiceHealth" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6953,6 +7328,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_REMOTE_MESSAGING" + android:description="@string/permdesc_foregroundServiceRemoteMessaging" + android:label="@string/permlab_foregroundServiceRemoteMessaging" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6962,6 +7339,8 @@ <p>Protection level: normal|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED" + android:description="@string/permdesc_foregroundServiceSystemExempted" + android:label="@string/permlab_foregroundServiceSystemExempted" android:protectionLevel="normal|instant" /> <!-- Allows a regular application to use {@link android.app.Service#startForeground @@ -6974,11 +7353,23 @@ android:label="@string/permlab_foregroundServiceFileManagement" android:protectionLevel="normal|instant" /> + <!-- @FlaggedApi("android.content.pm.introduce_media_processing_type") + Allows a regular application to use {@link android.app.Service#startForeground + Service.startForeground} with the type "mediaProcessing". + <p>Protection level: normal|instant + --> + <permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROCESSING" + android:description="@string/permdesc_foregroundServiceMediaProcessing" + android:label="@string/permlab_foregroundServiceMediaProcessing" + android:protectionLevel="normal|instant" /> + <!-- Allows a regular application to use {@link android.app.Service#startForeground Service.startForeground} with the type "specialUse". <p>Protection level: normal|appop|instant --> <permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" + android:description="@string/permdesc_foregroundServiceSpecialUse" + android:label="@string/permlab_foregroundServiceSpecialUse" android:protectionLevel="normal|appop|instant" /> <!-- @SystemApi Allows to access all app shortcuts. @@ -7073,17 +7464,11 @@ android:protectionLevel="signature" /> <!-- @SystemApi Allows modifying accessibility state. + <p> The only approved role for this permission is COMPANION_DEVICE_APP_STREAMING. @hide --> <permission android:name="android.permission.MANAGE_ACCESSIBILITY" android:protectionLevel="signature|setup|recents|role" /> - <!-- @FlaggedApi("com.android.server.accessibility.motion_event_observing") - @hide - @TestApi - Allows an accessibility service to observe motion events without consuming them. --> - <permission android:name="android.permission.ACCESSIBILITY_MOTION_EVENT_OBSERVING" - android:protectionLevel="signature" /> - <!-- @SystemApi Allows an app to grant a profile owner access to device identifiers. <p>Not for use by third-party applications. @deprecated @@ -7121,16 +7506,6 @@ <permission android:name="android.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO" android:protectionLevel="signature|privileged|appop" /> - <!-- @SystemApi Required for the privileged assistant apps targeting - {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} - that receive training data from a sandboxed {@link HotwordDetectionService} or - {@link VisualQueryDetectionService}. - <p>Protection level: internal|appop - @FlaggedApi("android.permission.flags.voice_activation_permission_apis") - @hide --> - <permission android:name="android.permission.RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA" - android:protectionLevel="internal|appop" /> - <!-- @SystemApi Allows requesting the framework broadcast the {@link Intent#ACTION_DEVICE_CUSTOMIZATION_READY} intent. @hide --> @@ -7198,8 +7573,8 @@ <!-- Allows input events to be monitored. Very dangerous! @hide --> <permission android:name="android.permission.MONITOR_INPUT" android:protectionLevel="signature|recents" /> - <!-- Allows the use of FLAG_SLIPPERY, which permits touch events to slip from the current - window to the window where the touch currently is on top of. @hide --> + <!-- @SystemApi Allows the use of FLAG_SLIPPERY, which permits touch events to slip from the + current window to the window where the touch currently is on top of. @hide --> <permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES" android:protectionLevel="signature|privileged|recents|role" /> <!-- Allows the caller to change the associations between input devices and displays. @@ -7261,6 +7636,11 @@ <permission android:name="android.permission.RESET_APP_ERRORS" android:protectionLevel="signature" /> + <!-- @hide Allows ThemeOverlayController to delay launch of Home / SetupWizard on boot, ensuring + Theme Palettes and Colors are ready --> + <permission android:name="android.permission.SET_THEME_OVERLAY_CONTROLLER_READY" + android:protectionLevel="signature|setup" /> + <!-- @hide Allows an application to create/destroy input consumer. --> <permission android:name="android.permission.INPUT_CONSUMER" android:protectionLevel="signature" /> @@ -7290,38 +7670,34 @@ <permission android:name="android.permission.MANAGE_GAME_MODE" android:protectionLevel="signature|privileged" /> + <!-- @TestApi Allows setting the game service provider, meant for tests only. + @hide --> + <permission android:name="android.permission.SET_GAME_SERVICE" + android:protectionLevel="signature" /> + <!-- @SystemApi Allows accessing the frame rate per second of a given application - @hide --> + @hide --> <permission android:name="android.permission.ACCESS_FPS_COUNTER" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows managing the GameService APIs - @hide --> + <!-- @SystemApi Allows the GameService provider to create GameSession and call GameSession + APIs and overlay a view on top of the game's Activity. + @hide --> <permission android:name="android.permission.MANAGE_GAME_ACTIVITY" android:protectionLevel="signature|privileged" /> - <!-- Allows managing the Game service - @hide @TestApi Used only for testing. --> - <permission android:name="android.permission.SET_GAME_SERVICE" - android:protectionLevel="signature" /> - <!-- @SystemApi Allows the holder to register callbacks to inform the RebootReadinessManager when they are performing reboot-blocking work. @hide --> <permission android:name="android.permission.SIGNAL_REBOOT_READINESS" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to change the touch mode state. - @hide --> - <permission android:name="android.permission.MODIFY_TOUCH_MODE_STATE" - android:protectionLevel="signature" /> - <!-- @SystemApi Allows the holder to launch an Intent Resolver flow with custom presentation and/or targets. - @FlaggedApi("android.service.chooser.support_nfc_resolver") + @FlaggedApi("android.nfc.enable_nfc_mainline") @hide --> <permission android:name="android.permission.SHOW_CUSTOMIZED_RESOLVER" - android:protectionLevel="signature|privileged" /> + android:protectionLevel="signature|privileged" /> <!-- @hide Allows an application to get a People Tile preview for a given shortcut. --> <permission android:name="android.permission.GET_PEOPLE_TILE_PREVIEW" @@ -7339,7 +7715,10 @@ android:protectionLevel="signature|privileged" /> <!-- Allows an application to read nearby streaming policy. The policy controls - whether to allow the device to stream its notifications and apps to nearby devices. --> + whether to allow the device to stream its notifications and apps to nearby devices. + Applications that are not the device owner will need this permission to call + {@link android.app.admin.DevicePolicyManager#getNearbyNotificationStreamingPolicy} or + {@link android.app.admin.DevicePolicyManager#getNearbyAppStreamingPolicy}. --> <permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" android:protectionLevel="normal" /> @@ -7375,6 +7754,7 @@ android:protectionLevel="normal" /> <uses-permission android:name="android.permission.ENFORCE_UPDATE_OWNERSHIP" /> + <!-- Allows an application to take screenshots of layers that normally would be blacked out when a screenshot is taken. Specifically, layers that have the flag {@link android.view.SurfaceControl#SECURE} will be screenshot if the caller requests to @@ -7385,16 +7765,8 @@ <permission android:name="android.permission.CAPTURE_BLACKOUT_CONTENT" android:protectionLevel="signature" /> - <!-- Allows read only access to phone state with a non dangerous permission, - including the information like cellular network type, software version. --> - <permission android:name="android.permission.READ_BASIC_PHONE_STATE" - android:permissionGroup="android.permission-group.UNDEFINED" - android:label="@string/permlab_readBasicPhoneState" - android:description="@string/permdesc_readBasicPhoneState" - android:protectionLevel="normal" /> - <!-- @SystemApi Allows an application to query over global data in AppSearch. - @hide --> + @hide --> <permission android:name="android.permission.READ_GLOBAL_APP_SEARCH_DATA" android:protectionLevel="internal|role" /> @@ -7465,6 +7837,19 @@ <permission android:name="android.permission.MANAGE_SAFETY_CENTER" android:protectionLevel="internal|installer|role" /> + <!-- @SystemApi Allows an application to access the AmbientContextEvent service. + @hide + --> + <permission android:name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT" + android:protectionLevel="signature|privileged|role"/> + + <!-- @SystemApi Required by a AmbientContextEventDetectionService + to ensure that only the service with this permission can bind to it. + @hide + --> + <permission android:name="android.permission.BIND_AMBIENT_CONTEXT_DETECTION_SERVICE" + android:protectionLevel="signature" /> + <!-- @SystemApi Allows an app to set keep-clear areas without restrictions on the size or number of keep-clear areas (see {@link android.view.View#setPreferKeepClearRects}). When the system arranges floating windows onscreen, it might decide to ignore keep-clear @@ -7481,9 +7866,23 @@ <permission android:name="android.permission.SET_UNRESTRICTED_GESTURE_EXCLUSION" android:protectionLevel="signature|privileged|recents" /> + <!-- @SystemApi Allows TV input apps and TV apps to use TIS extension interfaces for + domain-specific features. + <p>Protection level: signature|privileged|vendorPrivileged + <p>Not for use by third-party applications. + @hide + --> + <permission android:name="android.permission.TIS_EXTENSION_INTERFACE" + android:protectionLevel="signature|privileged|vendorPrivileged" /> + + <!-- @SystemApi Allows an application to write to the security log buffer in logd. + @hide --> + <permission android:name="android.permission.WRITE_SECURITY_LOG" + android:protectionLevel="signature|privileged" /> + <!-- Allows an UID to be visible to the application based on an interaction between the two apps. This permission is not intended to be held by apps. - @hide @TestApi --> + @hide @TestApi @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) --> <permission android:name="android.permission.MAKE_UID_VISIBLE" android:protectionLevel="signature" /> @@ -7491,21 +7890,77 @@ @hide --> <permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART" android:protectionLevel="signature" /> + + <!-- Allows low-level access to re-mapping modifier keys. + <p>Not for use by third-party applications. + @hide + @TestApi --> + <permission android:name="android.permission.REMAP_MODIFIER_KEYS" + android:protectionLevel="signature" /> + + <!-- Allows low-level access to monitor keyboard backlight changes. + <p>Not for use by third-party applications. + @hide --> + <permission android:name="android.permission.MONITOR_KEYBOARD_BACKLIGHT" + android:protectionLevel="signature" /> + + <!-- Allows low-level access to monitor sticky modifier state changes when A11Y Sticky keys + feature is enabled. + <p>Not for use by third-party applications. + @hide --> + <permission android:name="android.permission.MONITOR_STICKY_MODIFIER_STATE" + android:protectionLevel="signature" /> + <uses-permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART" /> <!-- Allows financed device kiosk apps to perform actions on the Device Lock service - @hide @TestApi @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) --> + <p>Protection level: internal|role + <p>Intended for use by the FINANCED_DEVICE_KIOSK role only. + --> <permission android:name="android.permission.MANAGE_DEVICE_LOCK_STATE" android:protectionLevel="internal|role" /> - <!-- Allows an app to turn on the screen on, e.g. with - {@link android.os.PowerManager#ACQUIRE_CAUSES_WAKEUP}. - <p>Intended to only be used by home automation apps. + <!-- @SystemApi Required by a WearableSensingService to + ensure that only the caller with this permission can bind to it. + <p> Protection level: signature + @hide --> - <permission android:name="android.permission.TURN_SCREEN_ON" - android:label="@string/permlab_turnScreenOn" - android:description="@string/permdesc_turnScreenOn" - android:protectionLevel="signature|privileged|appop" /> + <permission android:name="android.permission.BIND_WEARABLE_SENSING_SERVICE" + android:protectionLevel="signature" /> + + <!-- @SystemApi Allows an app to manage the wearable sensing service. + <p>Protection level: signature|privileged + @hide + --> + <permission android:name="android.permission.MANAGE_WEARABLE_SENSING_SERVICE" + android:protectionLevel="signature|privileged" /> + + <!-- @SystemApi Allows an app to use the on-device intelligence service. + <p>Protection level: signature|privileged + @hide + @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") + --> + <permission android:name="android.permission.USE_ON_DEVICE_INTELLIGENCE" + android:protectionLevel="signature|privileged" /> + + + <!-- @SystemApi Allows an app to bind the on-device intelligence service. + <p>Protection level: signature|privileged + @hide + @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") + --> + <permission android:name="android.permission.BIND_ON_DEVICE_INTELLIGENCE_SERVICE" + android:protectionLevel="signature|privileged" /> + + + <!-- @SystemApi Allows an app to bind the on-device sandboxed service. + <p>Protection level: signature|privileged + @hide + @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") + --> + <permission android:name="android.permission.BIND_ON_DEVICE_SANDBOXED_INFERENCE_SERVICE" + android:protectionLevel="signature"/> + <!-- Allows applications to use the user-initiated jobs API. For more details see {@link android.app.job.JobInfo.Builder#setUserInitiated}. @@ -7514,52 +7969,23 @@ <permission android:name="android.permission.RUN_USER_INITIATED_JOBS" android:protectionLevel="normal"/> - <!-- Allows a browser to invoke the set of credential candidate query apis. - <p>Protection level: normal - --> - <permission android:name="android.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS" - android:protectionLevel="normal" /> - - <!-- Allows browsers to call on behalf of another app by passing in a custom origin. - <p>Protection level: normal - --> - <permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ORIGIN" - android:protectionLevel="normal"/> - - <!-- Allows specifying candidate credential providers to be queried in Credential Manager - get flows, or to be preferred as a default in the Credential Manager create flows. - <p>Protection level: normal --> - <permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS" - android:protectionLevel="normal"/> - - <!-- Allows permission to use Credential Manager UI for providing and saving credentials - @hide --> - <permission android:name="android.permission.LAUNCH_CREDENTIAL_SELECTOR" - android:protectionLevel="signature" /> - - <!-- Allows an app to list Credential Manager providers. + <!-- @FlaggedApi("android.app.job.backup_jobs_exemption") + Gives applications with a <b>major use case</b> of backing-up or syncing content increased + job execution allowance in order to complete the related work. The jobs must have a valid + content URI trigger and network constraint set. + <p>This is a special access permission that can be revoked by the system or the user. + <p>Protection level: signature|privileged|appop @hide - --> - <permission android:name="android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS" - android:protectionLevel="signature|privileged"/> - - <!-- Allows a system application to be registered with credential manager without - having to be enabled by the user. - @SystemApi - @hide --> - <permission android:name="android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE" - android:protectionLevel="signature|privileged" /> - - <!-- Allows an application to be able to store and retrieve credentials from a remote - device. --> - <permission android:name="android.permission.PROVIDE_REMOTE_CREDENTIALS" - android:protectionLevel="signature|privileged|role" /> + --> + <permission android:name="android.permission.RUN_BACKUP_JOBS" + android:protectionLevel="signature|privileged|appop"/> <!-- Allows an app access to the installer provided app metadata. @SystemApi - @hide --> + @hide + --> <permission android:name="android.permission.GET_APP_METADATA" - android:protectionLevel="signature|installer" /> + android:protectionLevel="signature|installer|verifier" /> <!-- @hide @SystemApi Allows an application to stage HealthConnect's remote data so that HealthConnect can later integrate it. --> @@ -7572,15 +7998,15 @@ <permission android:name="android.permission.DELETE_STAGED_HEALTH_CONNECT_REMOTE_DATA" android:protectionLevel="signature" /> - <!-- @hide @TestApi Allows CTS tests running in Sandbox mode to launch activities --> + <!-- @hide @TestApi Allows tests running in CTS-in-sandbox mode to launch activities --> <permission android:name="android.permission.START_ACTIVITIES_FROM_SDK_SANDBOX" android:protectionLevel="signature" /> <!-- @SystemApi Allows the holder to call health connect migration APIs. - @hide --> + @hide --> <permission android:name="android.permission.MIGRATE_HEALTH_CONNECT_DATA" - android:protectionLevel="signature|knownSigner" - android:knownCerts="@array/config_healthConnectMigrationKnownSigners" /> + android:protectionLevel="signature|knownSigner" + android:knownCerts="@array/config_healthConnectMigrationKnownSigners" /> <!-- @SystemApi Allows an app to query apps in clone profile. The permission is bidirectional in nature, i.e. cloned apps would be able to query apps in root user. @@ -7623,6 +8049,7 @@ <permission android:name="android.permission.GET_ANY_PROVIDER_TYPE" android:protectionLevel="signature" /> + <!-- @hide Allows internal applications to read and synchronize non-core flags. Apps without this permission can only read a subset of flags specifically intended for use in "core", (i.e. third party apps). Apps with this permission can define their @@ -7631,14 +8058,14 @@ <p>Protection level: signature --> <permission android:name="android.permission.SYNC_FLAGS" - android:protectionLevel="signature" /> + android:protectionLevel="signature" /> <!-- @hide Allows internal applications to override flags in the FeatureFlags service. <p>Not for use by third-party applications. <p>Protection level: signature --> <permission android:name="android.permission.WRITE_FLAGS" - android:protectionLevel="signature" /> + android:protectionLevel="signature" /> <!-- @hide @SystemApi @FlaggedApi("android.app.get_binding_uid_importance") @@ -7650,22 +8077,14 @@ android:protectionLevel="signature|privileged" /> <!-- @hide Allows internal applications to manage displays. - <p>This means intercept internal signals about displays being (dis-)connected - and being able to enable or disable connected displays. - <p>Not for use by third-party applications. - <p>Protection level: signature + <p>This means intercept internal signals about displays being (dis-)connected + and being able to enable or disable the external displays. + <p>Not for use by third-party applications. + <p>Protection level: signature --> <permission android:name="android.permission.MANAGE_DISPLAYS" android:protectionLevel="signature" /> - <!-- @SystemApi Allows apps to reset hotword training data egress count for testing. - <p>CTS tests will use UiAutomation.AdoptShellPermissionIdentity() to gain access. - <p>Protection level: signature - @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") - @hide --> - <permission android:name="android.permission.RESET_HOTWORD_TRAINING_DATA_EGRESS_COUNT" - android:protectionLevel="signature" /> - <!-- @SystemApi Allows an app to track all preparations for a complete factory reset. <p>Protection level: signature|privileged @FlaggedApi("android.permission.flags.factory_reset_prep_permission_apis") @@ -7689,6 +8108,64 @@ <permission android:name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" android:protectionLevel="signature|privileged" /> + <!-- Allows internal applications to restrict display modes + <p>Protection level: signature + @FlaggedApi("com.android.server.display.feature.flags.enable_restrict_display_modes") + @hide + --> + <permission android:name="android.permission.RESTRICT_DISPLAY_MODES" + android:protectionLevel="signature" /> + + <!-- @hide @SystemApi + @FlaggedApi("com.android.server.notification.flags.redact_otp_notifications_from_untrusted_listeners") + Allows apps with a NotificationListenerService to receive notifications with sensitive + information + <p>Apps with a NotificationListenerService without this permission will not be able + to view certain types of sensitive information contained in notifications + <p>Protection level: signature|role + --> + <permission android:name="android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS" + android:protectionLevel="signature|role" /> + + <!-- @SystemApi + @FlaggedApi("android.app.bic_client") + Allows app to call BackgroundInstallControlManager API to retrieve silently installed apps + for all users on device. + <p>Apps with a BackgroundInstallControlManager client will not be able to call any API without + this permission. + <p>Protection level: signature|role + @hide + --> + <permission android:name="android.permission.GET_BACKGROUND_INSTALLED_PACKAGES" + android:protectionLevel="signature|role" /> + + <!-- @SystemApi Allows an application to read the system grammatical gender. + @FlaggedApi("android.app.system_terms_of_address_enabled") + <p>Protection level: signature|privileged + @hide + --> + <permission android:name="android.permission.READ_SYSTEM_GRAMMATICAL_GENDER" + android:protectionLevel="signature|privileged"/> + + <!-- @SystemApi + @FlaggedApi("android.content.pm.emergency_install_permission") + Allows each app store in the system image to designate another app in the system image to + update the app store + <p>Protection level: signature|privileged + @hide + --> + <permission android:name="android.permission.EMERGENCY_INSTALL_PACKAGES" + android:protectionLevel="signature|privileged"/> + + <!-- Allows internal applications to override screen timeout temporarily + <p>Protection level: signature + <p>Not for use by third-party applications. + @FlaggedApi("com.android.server.power.feature.flags.enable_early_screen_timeout_detector") + @hide + --> + <permission android:name="android.permission.SCREEN_TIMEOUT_OVERRIDE" + android:protectionLevel="signature" /> + <!-- Attribution for Geofencing service. --> <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/> <!-- Attribution for Country Detector. --> @@ -7709,6 +8186,9 @@ <p>Not for use by third-party applications.</p> --> <attribution android:tag="MusicRecognitionManagerService" android:label="@string/music_recognition_manager_service"/> + <!-- Attribution for Device Policy Manager service. --> + <attribution android:tag="DevicePolicyManagerService" + android:label="@string/device_policy_manager_service"/> <application android:process="system" android:persistent="true" @@ -7723,22 +8203,6 @@ android:defaultToDeviceProtectedStorage="true" android:forceQueryable="true" android:directBootAware="true"> - <activity android:name="com.android.internal.app.ChooserActivity" - android:theme="@style/Theme.DeviceDefault.Chooser" - android:finishOnCloseSystemDialogs="true" - android:excludeFromRecents="true" - android:documentLaunchMode="never" - android:relinquishTaskIdentity="true" - android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" - android:process=":ui" - android:exported="true" - android:visibleToInstantApps="true"> - <intent-filter android:priority="100"> - <action android:name="android.intent.action.CHOOSER" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.VOICE" /> - </intent-filter> - </activity> <activity android:name="com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity" android:exported="false" android:theme="@style/Theme.DeviceDefault.Dialog.Alert.DayNight" @@ -7768,10 +8232,25 @@ <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> + <activity android:name="com.android.internal.app.NfcResolverActivity" + android:theme="@style/Theme.Dialog.Alert" + android:finishOnCloseSystemDialogs="true" + android:excludeFromRecents="true" + android:multiprocess="true" + android:permission="android.permission.SHOW_CUSTOMIZED_RESOLVER" + android:exported="true"> + <intent-filter android:priority="100" > + <action android:name="android.nfc.action.SHOW_NFC_RESOLVER" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> <activity android:name="com.android.internal.app.IntentForwarderActivity" android:finishOnCloseSystemDialogs="true" - android:theme="@style/Theme.Translucent.NoTitleBar" + android:theme="@style/Theme.DeviceDefault.Resolver" android:excludeFromRecents="true" + android:documentLaunchMode="never" + android:relinquishTaskIdentity="true" + android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden" android:label="@string/user_owner_label" android:exported="true" android:visibleToInstantApps="true" @@ -7796,8 +8275,9 @@ android:process=":ui"> </activity> <activity android:name="com.android.internal.app.PlatLogoActivity" - android:theme="@style/Theme.DeviceDefault.Wallpaper.NoTitleBar" + android:theme="@style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden" + android:enableOnBackInvokedCallback="true" android:icon="@drawable/platlogo" android:process=":ui"> </activity> @@ -7869,12 +8349,6 @@ </intent-filter> </activity> - <activity android:name="com.android.internal.app.NetInitiatedActivity" - android:theme="@style/Theme.Dialog.Confirmation" - android:excludeFromRecents="true" - android:process=":ui"> - </activity> - <activity android:name="com.android.internal.app.SystemUserHomeActivity" android:enabled="false" android:process=":ui" @@ -7912,6 +8386,12 @@ android:process=":ui"> </activity> + <activity android:name="com.android.internal.app.SetScreenLockDialogActivity" + android:theme="@style/Theme.Dialog.Confirmation" + android:excludeFromRecents="true" + android:process=":ui"> + </activity> + <activity android:name="com.android.internal.app.BlockedAppActivity" android:theme="@style/Theme.Dialog.Confirmation" android:excludeFromRecents="true" @@ -7919,6 +8399,12 @@ android:process=":ui"> </activity> + <activity android:name="com.android.internal.app.BlockedAppStreamingActivity" + android:theme="@style/Theme.Dialog.Confirmation" + android:excludeFromRecents="true" + android:process=":ui"> + </activity> + <activity android:name="com.android.internal.app.LaunchAfterAuthenticationActivity" android:theme="@style/Theme.Translucent.NoTitleBar" android:excludeFromRecents="true" @@ -7944,6 +8430,13 @@ android:exported="false"> </activity> + <activity android:name="android.service.games.GameSessionTrampolineActivity" + android:excludeFromRecents="true" + android:exported="true" + android:permission="android.permission.MANAGE_GAME_ACTIVITY" + android:theme="@style/Theme.GameSessionTrampoline"> + </activity> + <receiver android:name="com.android.server.BootReceiver" android:exported="true" android:systemUserOnly="true"> @@ -8085,6 +8578,16 @@ </intent-filter> </receiver> + <!-- Broadcast Receiver listens to sufficient verifier broadcast from Package Manager + when installing new SDK. Verification of SDK code during installation time is run + to determine compatibility with privacy sandbox restrictions. --> + <receiver android:name="com.android.server.sdksandbox.SdkSandboxVerifierReceiver" + android:exported="false"> + <intent-filter> + <action android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION"/> + </intent-filter> + </receiver> + <service android:name="android.hardware.location.GeofenceHardwareService" android:permission="android.permission.LOCATION_HARDWARE" android:exported="false" /> @@ -8094,6 +8597,11 @@ android:permission="android.permission.BIND_JOB_SERVICE" > </service> + <service android:name="com.android.server.SmartStorageMaintIdler" + android:exported="true" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> + <service android:name="com.android.server.ZramWriteback" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE" > @@ -8121,6 +8629,18 @@ android:permission="android.permission.BIND_JOB_SERVICE"> </service> + <service android:name="com.android.server.selinux.SelinuxAuditLogsService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + + <service android:name="com.android.server.compos.IsolatedCompilationJobService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + + <service android:name="com.android.system.virtualmachine.SecretkeeperJobService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + <service android:name="com.android.server.PruneInstantAppsJobService" android:permission="android.permission.BIND_JOB_SERVICE" > </service> @@ -8157,6 +8677,10 @@ android:permission="android.permission.BIND_JOB_SERVICE" > </service> + <service android:name="com.android.server.pm.GentleUpdateHelper$Service" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> + <service android:name="com.android.server.autofill.AutofillCompatAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" @@ -8171,6 +8695,42 @@ android:permission="android.permission.BIND_JOB_SERVICE"> </service> + <service android:name="com.android.server.companion.association.InactiveAssociationsRemovalService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + + <service android:name="com.android.server.appsearch.contactsindexer.ContactsIndexerMaintenanceService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + + <service android:name="com.android.server.BinaryTransparencyService$UpdateMeasurementsJobService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + + <service android:name="com.android.server.notification.ReviewNotificationPermissionsJobService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + + <service android:name="com.android.server.notification.NotificationHistoryJobService" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> + + <service android:name="com.android.server.notification.NotificationBitmapJobService" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> + + <service android:name="com.android.server.healthconnect.HealthConnectDailyService" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> + + <service android:name="com.android.server.healthconnect.migration.MigrationBroadcastJobService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + + <service android:name="com.android.server.healthconnect.backuprestore.BackupRestore$BackupRestoreJobService" + android:permission="android.permission.BIND_JOB_SERVICE"> + </service> + <service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader" android:exported="false"> <intent-filter> @@ -8178,6 +8738,38 @@ </intent-filter> </service> + <!-- TODO: Move to ExtServices or relevant component. --> + <service android:name="android.service.selectiontoolbar.DefaultSelectionToolbarRenderService" + android:permission="android.permission.BIND_SELECTION_TOOLBAR_RENDER_SERVICE" + android:process=":ui" + android:exported="false"> + <intent-filter> + <action android:name="android.service.selectiontoolbar.SelectionToolbarRenderService"/> + </intent-filter> + </service> + + <service android:name="com.android.server.art.BackgroundDexoptJobService" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> + + <service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncInCallService" + android:permission="android.permission.BIND_INCALL_SERVICE" + android:exported="true"> + <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS" + android:value="true" /> + <intent-filter> + <action android:name="android.telecom.InCallService"/> + </intent-filter> + </service> + + <service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncConnectionService" + android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" + android:exported="true"> + <intent-filter> + <action android:name="android.telecom.ConnectionService"/> + </intent-filter> + </service> + <provider android:name="com.android.server.textclassifier.IconsContentProvider" android:authorities="com.android.textclassifier.icons" @@ -8186,6 +8778,10 @@ android:exported="true"> </provider> + <meta-data + android:name="com.android.server.patch.25239169" + android:value="true" /> + </application> </manifest> diff --git a/tests/cts/permissionpolicy/res/raw/automotive_android_manifest.xml b/tests/cts/permissionpolicy/res/raw/automotive_android_manifest.xml index dcd8ec4bd..783cd7f6b 100644 --- a/tests/cts/permissionpolicy/res/raw/automotive_android_manifest.xml +++ b/tests/cts/permissionpolicy/res/raw/automotive_android_manifest.xml @@ -206,6 +206,42 @@ android:protectionLevel="signature|privileged" android:label="@string/car_permission_label_control_car_powertrain" android:description="@string/car_permission_desc_control_car_powertrain"/> + <permission android:name="android.car.permission.READ_CAR_SEAT_BELTS" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_read_car_seat_belts" + android:description="@string/car_permission_desc_read_car_seat_belts"/> + <permission android:name="android.car.permission.CONTROL_CAR_DYNAMICS_STATE" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_control_car_dynamics_state" + android:description="@string/car_permission_desc_control_car_dynamics_state"/> + <permission android:name="android.car.permission.READ_IMPACT_SENSORS" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_read_impact_sensors" + android:description="@string/car_permission_desc_read_impact_sensors"/> + <permission android:name="android.car.permission.READ_HEAD_UP_DISPLAY_STATUS" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_read_head_up_display_status" + android:description="@string/car_permission_desc_read_head_up_display_status"/> + <permission android:name="android.car.permission.CONTROL_HEAD_UP_DISPLAY" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_control_head_up_display" + android:description="@string/car_permission_desc_control_head_up_display"/> + <permission android:name="android.car.permission.READ_VALET_MODE" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_read_valet_mode" + android:description="@string/car_permission_desc_read_valet_mode"/> + <permission android:name="android.car.permission.CONTROL_VALET_MODE" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_control_valet_mode" + android:description="@string/car_permission_desc_control_valet_mode"/> + <permission android:name="android.car.permission.READ_CAR_AIRBAGS" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_read_car_airbags" + android:description="@string/car_permission_desc_read_car_airbags"/> + <permission android:name="android.car.permission.READ_ULTRASONICS_SENSOR_DATA" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_read_ultrasonics_sensor_data" + android:description="@string/car_permission_desc_read_ultrasonics_sensor_data"/> <permission android:name="android.car.permission.CAR_NAVIGATION_MANAGER" android:protectionLevel="signature|privileged" android:label="@string/car_permission_car_navigation_manager" @@ -570,8 +606,18 @@ android:protectionLevel="signature|privileged" android:label="@string/car_permission_label_control_windshield_wipers" android:description="@string/car_permission_desc_control_windshield_wipers"/> - <permission android:name="android.car.permission.QUERY_DISPLAY_COMPATIBILITY" + <permission android:name="android.car.permission.MANAGE_DISPLAY_COMPATIBILITY" android:protectionLevel="signature|privileged" - android:label="@string/car_permission_label_query_display_compatibility" - android:description="@string/car_permission_desc_query_display_compatibility"/> + android:label="@string/car_permission_label_manage_display_compatibility" + android:description="@string/car_permission_desc_manage_display_compatibility"/> + <permission + android:name="android.car.permission.READ_PERSIST_TETHERING_SETTINGS" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_read_persist_tethering_settings" + android:description="@string/car_permission_desc_read_persist_tethering_settings" /> + <permission + android:name="android.car.permission.BIND_APP_CARD_PROVIDER" + android:protectionLevel="signature|privileged" + android:label="@string/car_permission_label_bind_app_card_provider" + android:description="@string/car_permission_desc_bind_app_card_provider" /> </manifest> diff --git a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/ContactsProviderTest.java b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/ContactsProviderTest.java index d8dc11a14..f34170a9b 100644 --- a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/ContactsProviderTest.java +++ b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/ContactsProviderTest.java @@ -21,7 +21,8 @@ import android.content.ContentValues; import android.platform.test.annotations.AppModeFull; import android.provider.ContactsContract; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify that deprecated contacts permissions are not enforced. diff --git a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoCaptureAudioOutputPermissionTest.java b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoCaptureAudioOutputPermissionTest.java index 0f7638694..ef38573ab 100644 --- a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoCaptureAudioOutputPermissionTest.java +++ b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoCaptureAudioOutputPermissionTest.java @@ -21,7 +21,8 @@ import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder.AudioSource; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify the capture system video output permission requirements. diff --git a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoReceiveSmsPermissionTest.java b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoReceiveSmsPermissionTest.java index c3a29ccb3..ecd31e620 100644 --- a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoReceiveSmsPermissionTest.java +++ b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/NoReceiveSmsPermissionTest.java @@ -28,10 +28,13 @@ import android.platform.test.annotations.SystemUserOnly; import android.telephony.SmsManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.test.AndroidTestCase; import android.text.TextUtils; import android.util.Log; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -55,6 +58,14 @@ public class NoReceiveSmsPermissionTest extends AndroidTestCase { private static final String LOG_TAG = "NoReceiveSmsPermissionTest"; + // List of carrier-id that does not support loop back messages + // This is copied from + // cts/tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java + public static final List<Integer> UNSUPPORT_LOOP_BACK_MESSAGES = + Arrays.asList( + 1 // "T-Mobile - US" + ); + private Semaphore mSemaphore = new Semaphore(0); /** @@ -101,6 +112,11 @@ public class NoReceiveSmsPermissionTest extends AndroidTestCase { return; } + int carrierId = getContext().getSystemService(TelephonyManager.class).getSimCarrierId(); + assertFalse("[RERUN] Carrier [carrier-id: " + carrierId + "] does not support " + + "loop back messages. Use another carrier.", + UNSUPPORT_LOOP_BACK_MESSAGES.contains(carrierId)); + AppSpecificSmsReceiver receiver = new AppSpecificSmsReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(TELEPHONY_SMS_RECEIVED); diff --git a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionMaxSdkVersionTest.java b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionMaxSdkVersionTest.java index b02b32f22..8bf3e83a4 100644 --- a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionMaxSdkVersionTest.java +++ b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionMaxSdkVersionTest.java @@ -19,7 +19,8 @@ package android.permission.cts; import android.content.pm.PackageManager; import android.os.Process; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify permission behaviors with android:maxSdkVersion diff --git a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionPolicyTest.java b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionPolicyTest.java index 94bd2be1b..c28b5d560 100644 --- a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionPolicyTest.java +++ b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/PermissionPolicyTest.java @@ -19,6 +19,7 @@ package android.permissionpolicy.cts; import static android.content.pm.PermissionInfo.FLAG_INSTALLED; import static android.content.pm.PermissionInfo.PROTECTION_MASK_BASE; import static android.os.Build.VERSION.SECURITY_PATCH; +import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; import static com.google.common.truth.Truth.assertWithMessage; @@ -32,13 +33,12 @@ import android.content.pm.PermissionInfo; import android.os.Process; import android.os.SystemProperties; import android.platform.test.annotations.AppModeFull; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Xml; -import com.android.modules.utils.build.SdkLevel; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -87,6 +87,7 @@ public class PermissionPolicyTest { private static final String ATTR_PERMISSION_FLAGS = "permissionFlags"; private static final String ATTR_PROTECTION_LEVEL = "protectionLevel"; private static final String ATTR_BACKGROUND_PERMISSION = "backgroundPermission"; + private static final String ATTR_FEATURE_FLAG = "featureFlag"; private static final Context sContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); @@ -117,13 +118,17 @@ public class PermissionPolicyTest { declaredGroupsSet.add(declaredGroup.name); } + boolean filterFlaggedPermissions = sContext.getPackageManager() + .getApplicationInfo(PLATFORM_PACKAGE_NAME, 0).minSdkVersion <= UPSIDE_DOWN_CAKE; + Set<String> expectedPermissionGroups = loadExpectedPermissionGroupNames( R.raw.android_manifest); List<ExpectedPermissionInfo> expectedPermissions = loadExpectedPermissions( - R.raw.android_manifest); + R.raw.android_manifest, filterFlaggedPermissions); if (sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { - expectedPermissions.addAll(loadExpectedPermissions(R.raw.automotive_android_manifest)); + expectedPermissions.addAll(loadExpectedPermissions(R.raw.automotive_android_manifest, + filterFlaggedPermissions)); String carServicePackageName = SystemProperties.get("ro.android.car.carservice.package", null); @@ -301,8 +306,11 @@ public class PermissionPolicyTest { return false; } - private List<ExpectedPermissionInfo> loadExpectedPermissions(int resourceId) throws Exception { + private List<ExpectedPermissionInfo> loadExpectedPermissions(int resourceId, + boolean filterFlaggedPermissions) throws Exception { List<ExpectedPermissionInfo> permissions = new ArrayList<>(); + DeviceFlagsValueProvider flagsValueProvider = new DeviceFlagsValueProvider(); + flagsValueProvider.setUp(); try (InputStream in = sContext.getResources().openRawResource(resourceId)) { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, null); @@ -315,6 +323,22 @@ public class PermissionPolicyTest { continue; } if (TAG_PERMISSION.equals(parser.getName())) { + if (filterFlaggedPermissions) { + String featureFlag = parser.getAttributeValue(null, ATTR_FEATURE_FLAG); + if (featureFlag != null) { + featureFlag = featureFlag.trim(); + boolean invert = featureFlag.startsWith("!"); + if (invert) { + featureFlag = featureFlag.substring(1).trim(); + } + boolean flagEnabled = + invert != flagsValueProvider.getBoolean(featureFlag); + if (!flagEnabled) { + continue; + } + } + } + ExpectedPermissionInfo permissionInfo = new ExpectedPermissionInfo( parser.getAttributeValue(null, ATTR_NAME), parser.getAttributeValue(null, ATTR_PERMISSION_GROUP), @@ -328,6 +352,8 @@ public class PermissionPolicyTest { Log.e(LOG_TAG, "Unknown tag " + parser.getName()); } } + } finally { + flagsValueProvider.tearDownBeforeTest(); } return permissions; diff --git a/tests/cts/permissionui/Android.bp b/tests/cts/permissionui/Android.bp index 12fdbe533..07167284d 100644 --- a/tests/cts/permissionui/Android.bp +++ b/tests/cts/permissionui/Android.bp @@ -42,6 +42,7 @@ android_test { "CtsAccessibilityCommon", "platform-test-rules", "platform-test-annotations", + "android.permission.flags-aconfig-java", ], data: [ ":CtsPermissionPolicyApp25", @@ -77,5 +78,6 @@ android_test { "mts-permission", "automotive-tests", "automotive-general-tests", + "mcts-permission", ], } diff --git a/tests/cts/permissionui/UsePermissionAppLatest/AndroidManifest.xml b/tests/cts/permissionui/UsePermissionAppLatest/AndroidManifest.xml index 49e45fc01..0b92f5ef1 100644 --- a/tests/cts/permissionui/UsePermissionAppLatest/AndroidManifest.xml +++ b/tests/cts/permissionui/UsePermissionAppLatest/AndroidManifest.xml @@ -20,6 +20,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="android.permissionui.cts.usepermission"> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> + <uses-permission android:name="android.permission.CALL_PHONE"/> + <!-- Request two different permissions within the same group --> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> diff --git a/tests/cts/permissionui/src/android/permissionui/cts/AppPermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/AppPermissionTest.kt index 99fed6b79..cb356f6a3 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/AppPermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/AppPermissionTest.kt @@ -17,13 +17,20 @@ package android.permissionui.cts import android.Manifest.permission.ACCESS_COARSE_LOCATION +import android.Manifest.permission_group.PHONE +import android.Manifest.permission_group.SMS import android.os.Build +import android.permission.flags.Flags +import android.platform.test.annotations.RequiresFlagsEnabled +import android.platform.test.flag.junit.CheckFlagsRule +import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.provider.DeviceConfig import android.provider.Settings import android.provider.Settings.Secure.USER_SETUP_COMPLETE import androidx.test.filters.FlakyTest import androidx.test.filters.SdkSuppress import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until import com.android.compatibility.common.util.DeviceConfigStateChangerRule import com.android.modules.utils.build.SdkLevel import com.google.common.truth.Truth @@ -46,6 +53,9 @@ class AppPermissionTest : BaseUsePermissionTest() { true.toString() ) + @get:Rule + val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() + @Before fun setup() { Assume.assumeTrue("Permission rationale is only available on U+", SdkLevel.isAtLeastU()) @@ -203,11 +213,124 @@ class AppPermissionTest : BaseUsePermissionTest() { assertAppPermissionRationaleContainerIsVisible(false) } + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun installFromTrustedSource_enabledAllowRadioButtonAndIfClickedAndChecked() { + installPackageWithInstallSourceAndMetadataFromStore(APP_APK_NAME_LATEST) + + navigateToIndividualPermissionSetting(PHONE) + + assertAllowButtonIsEnabledAndClickAndChecked() + + pressBack() + } + + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun installFromDownloadedFile_disabledAllowRadioButtonAndIfClickedAndRestrictedSettingDialog_PhonePermGroup() { + installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + APP_APK_NAME_LATEST + ) + + navigateToIndividualPermissionSetting(PHONE) + + assertAllowButtonIsDisabledAndRestrictedSettingDialogPoppedUp() + + pressBack() + + pressBack() + } + + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun installFromDownloadedFile_disabledAllowRadioButtonAndIfClickedAndRestrictedSettingDialog_SMSPermGroup() { + installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + APP_APK_NAME_LATEST + ) + + navigateToIndividualPermissionSetting(SMS) + + assertAllowButtonIsDisabledAndRestrictedSettingDialogPoppedUp() + + pressBack() + + pressBack() + } + + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun installFromLocalFile_disabledAllowRadioButtonAndIfClickedAndRestrictedSettingDialog_PhonePermGroup() { + installPackageWithInstallSourceAndMetadataFromLocalFile(APP_APK_NAME_LATEST) + + navigateToIndividualPermissionSetting(PHONE) + + assertAllowButtonIsDisabledAndRestrictedSettingDialogPoppedUp() + + pressBack() + + pressBack() + } + + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun installFromLocalFile_disabledAllowRadioButtonAndIfClickedAndRestrictedSettingDialog_SMSPermGroup() { + installPackageWithInstallSourceAndMetadataFromLocalFile(APP_APK_NAME_LATEST) + + navigateToIndividualPermissionSetting(SMS) + + assertAllowButtonIsDisabledAndRestrictedSettingDialogPoppedUp() + + pressBack() + + pressBack() + } + + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun installWithUnspecifiedSource_disabledAllowRadioButtonAndIfClickedAndRestrictedSettingDialog_SMSPermGroup() { + installPackageViaSession(APP_APK_NAME_LATEST) + + navigateToIndividualPermissionSetting(SMS) + + assertAllowButtonIsDisabledAndRestrictedSettingDialogPoppedUp() + + pressBack() + + pressBack() + } + + private fun assertAllowButtonIsEnabledAndClickAndChecked() { + waitFindObject(By.res(ALLOW_RADIO_BUTTON).enabled(true).checked(false)) + .click() + waitFindObject(By.res(ALLOW_RADIO_BUTTON).checked(true)) + } + + private fun assertAllowButtonIsDisabledAndRestrictedSettingDialogPoppedUp() { + waitFindObject(By.res(ALLOW_RADIO_BUTTON).enabled(false)) + .clickAndWait(Until.newWindow(), TIMEOUT_MILLIS) + + waitFindObject(ENHANCED_CONFIRMATION_DIALOG_SELECTOR, TIMEOUT_MILLIS) + } + private fun assertAppPermissionRationaleContainerIsVisible(expected: Boolean) { findView(By.res(APP_PERMISSION_RATIONALE_CONTAINER_VIEW), expected) } companion object { private const val PERMISSION_RATIONALE_ENABLED = "permission_rationale_enabled" + private val ENHANCED_CONFIRMATION_DIALOG_SELECTOR = By.res( + "com.android.permissioncontroller:id/enhanced_confirmation_dialog_title"); } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt index b47fba56f..8c300e328 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/BasePermissionTest.kt @@ -111,6 +111,11 @@ abstract class BasePermissionTest { @JvmStatic protected val isAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) + @JvmStatic + protected val isAutomotiveSplitscreen = isAutomotive && + packageManager.hasSystemFeature( + /* PackageManager.FEATURE_CAR_SPLITSCREEN_MULTITASKING */ + "android.software.car.splitscreen_multitasking") } @get:Rule val screenRecordRule = ScreenRecordRule(false, false) @@ -276,9 +281,13 @@ abstract class BasePermissionTest { protected fun installPackageViaSession( apkName: String, appMetadata: PersistableBundle? = null, - packageSource: Int? = null + packageSource: Int? = null, + allowlistedRestrictedPermissions: Set<String>? = null ) { - val (sessionId, session) = createPackageInstallerSession(packageSource) + val (sessionId, session) = createPackageInstallerSession( + packageSource, + allowlistedRestrictedPermissions + ) runWithShellPermissionIdentity { writePackageInstallerSession(session, apkName) if (appMetadata != null) { @@ -443,10 +452,15 @@ abstract class BasePermissionTest { } private fun createPackageInstallerSession( - packageSource: Int? = null + packageSource: Int? = null, + allowlistedRestrictedPermissions: Set<String>? = null ): Pair<Int, PackageInstaller.Session> { // Create session val sessionParam = SessionParams(SessionParams.MODE_FULL_INSTALL) + allowlistedRestrictedPermissions?.let { + sessionParam.setWhitelistedRestrictedPermissions(it) + } + if (packageSource != null) { sessionParam.setPackageSource(packageSource) } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt index d24f4fd27..6babd1c06 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt @@ -29,6 +29,7 @@ import android.content.pm.PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE import android.content.pm.PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE import android.content.pm.PackageInstaller.PACKAGE_SOURCE_OTHER import android.content.pm.PackageInstaller.PACKAGE_SOURCE_STORE +import android.content.pm.PackageInstaller.SessionParams import android.content.pm.PackageManager import android.net.Uri import android.os.Build @@ -63,6 +64,7 @@ import org.junit.Before abstract class BaseUsePermissionTest : BasePermissionTest() { companion object { const val APP_APK_NAME_31 = "CtsUsePermissionApp31.apk" + const val APP_APK_NAME_LATEST = "CtsUsePermissionAppLatest.apk" const val APP_APK_PATH_22 = "$APK_DIRECTORY/CtsUsePermissionApp22.apk" const val APP_APK_PATH_22_CALENDAR_ONLY = @@ -116,6 +118,8 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { const val ALLOW_ALWAYS_RADIO_BUTTON = "com.android.permissioncontroller:id/allow_always_radio_button" + const val ALLOW_RADIO_BUTTON_FRAME = + "com.android.permissioncontroller:id/allow_radio_button_frame" const val ALLOW_RADIO_BUTTON = "com.android.permissioncontroller:id/allow_radio_button" const val ALLOW_FOREGROUND_RADIO_BUTTON = "com.android.permissioncontroller:id/allow_foreground_only_radio_button" @@ -242,6 +246,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { android.Manifest.permission.READ_CALENDAR to "@android:string/permgrouplab_calendar", android.Manifest.permission.WRITE_CALENDAR to "@android:string/permgrouplab_calendar", // SMS + android.Manifest.permission_group.SMS to "@android:string/permgrouplab_sms", android.Manifest.permission.SEND_SMS to "@android:string/permgrouplab_sms", android.Manifest.permission.RECEIVE_SMS to "@android:string/permgrouplab_sms", android.Manifest.permission.READ_SMS to "@android:string/permgrouplab_sms", @@ -261,6 +266,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { android.Manifest.permission.ACCESS_BACKGROUND_LOCATION to "@android:string/permgrouplab_location", // Phone + android.Manifest.permission_group.PHONE to "@android:string/permgrouplab_phone", android.Manifest.permission.READ_PHONE_STATE to "@android:string/permgrouplab_phone", android.Manifest.permission.CALL_PHONE to "@android:string/permgrouplab_phone", "android.permission.ACCESS_IMS_CALL_SERVICE" to "@android:string/permgrouplab_phone", @@ -443,6 +449,17 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { ) } + protected fun installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + apkName: String + ) { + installPackageViaSession( + apkName, + AppMetadata.createDefaultAppMetadata(), + PACKAGE_SOURCE_DOWNLOADED_FILE, + allowlistedRestrictedPermissions = SessionParams.RESTRICTED_PERMISSIONS_ALL + ) + } + protected fun installPackageWithInstallSourceAndMetadataFromOther(apkName: String) { installPackageViaSession( apkName, @@ -653,11 +670,26 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { waitForWindowTransition: Boolean = !isWatch, crossinline block: () -> Unit ) { + var shouldWaitForWindowTransition = waitForWindowTransition + // Do not wait for windowTransition after action is performed on auto, when permissions + // are being denied. The click deny function explicitly waits for window to transition + if (isAutomotive) { + var somePermissionsTrue = false + // http://go/nl-kt-best-practices#for-loop-vs-foreach + for (it in permissionAndExpectedGrantResults) { + somePermissionsTrue = somePermissionsTrue || it.second + } + // When all permissions being requested are to be denied + // do not wait for windowTransition + if (!somePermissionsTrue) { + shouldWaitForWindowTransition = false + } + } val result = requestAppPermissions( *permissions, askTwice = askTwice, - waitForWindowTransition = waitForWindowTransition, + waitForWindowTransition = shouldWaitForWindowTransition, block = block ) assertEquals( @@ -819,7 +851,11 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { } protected fun clickPermissionRequestDenyButton() { - if (isAutomotive || isWatch || isTv) { + if (isAutomotive) { + clickAndWaitForWindowTransition( + By.text(getPermissionControllerString(DENY_BUTTON_TEXT)) + ) + } else if (isWatch || isTv) { click(By.text(getPermissionControllerString(DENY_BUTTON_TEXT))) } else { click(By.res(DENY_BUTTON)) @@ -860,7 +896,9 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { protected fun clickPermissionRequestDenyAndDontAskAgainButton() { if (isAutomotive) { - click(By.text(getPermissionControllerString(DENY_AND_DONT_ASK_AGAIN_BUTTON_TEXT))) + clickAndWaitForWindowTransition( + By.text(getPermissionControllerString(DENY_AND_DONT_ASK_AGAIN_BUTTON_TEXT)) + ) } else if (isWatch) { click(By.text(getPermissionControllerString(DENY_BUTTON_TEXT))) } else { diff --git a/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt new file mode 100644 index 000000000..a55a48cf2 --- /dev/null +++ b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.permissionui.cts + +import android.Manifest +import android.app.AppOpsManager +import android.app.Instrumentation +import android.app.ecm.EnhancedConfirmationManager +import android.content.Context +import android.content.pm.PackageInstaller +import android.content.pm.PackageManager +import android.os.Build +import android.os.Process +import android.permission.flags.Flags +import android.platform.test.annotations.AppModeFull +import android.platform.test.annotations.RequiresFlagsEnabled +import android.platform.test.flag.junit.CheckFlagsRule +import android.platform.test.flag.junit.DeviceFlagsValueProvider +import androidx.test.filters.SdkSuppress +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.By +import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity +import com.android.compatibility.common.util.SystemUtil.eventually +import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Assume +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +@AppModeFull(reason = "Instant apps cannot install packages") +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = "VanillaIceCream") +@RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) +class EnhancedConfirmationManagerTest : BaseUsePermissionTest() { + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + private val context: Context = instrumentation.targetContext + private val ecm by lazy { context.getSystemService(EnhancedConfirmationManager::class.java)!! } + private val appOpsManager by lazy { context.getSystemService(AppOpsManager::class.java)!! } + private val packageManager by lazy { context.packageManager } + + @Rule + @JvmField + val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() + + @Before + fun assumeNotAutoTvOrWear() { + Assume.assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) + Assume.assumeFalse( + packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) + ) + Assume.assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun installedAppStartsWithModeDefault() { + installPackageWithInstallSourceAndMetadataFromStore(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + assertEquals( + getAppEcmState(context, appOpsManager, APP_PACKAGE_NAME), + AppOpsManager.MODE_DEFAULT + ) + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenStoreAppThenIsNotRestrictedFromProtectedSetting() { + installPackageWithInstallSourceAndMetadataFromStore(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + eventually { assertFalse(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) } + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenLocalAppThenIsRestrictedFromProtectedSetting() { + installPackageWithInstallSourceAndMetadataFromLocalFile(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + eventually { assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) } + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenDownloadedThenAppIsRestrictedFromProtectedSetting() { + installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + eventually { assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) } + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenExplicitlyRestrictedAppThenIsRestrictedFromProtectedSetting() { + installPackageWithInstallSourceAndMetadataFromStore(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + eventually { assertFalse(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) } + setAppEcmState(context, appOpsManager, APP_PACKAGE_NAME, AppOpsManager.MODE_ERRORED) + eventually { assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) } + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenRestrictedAppThenIsNotRestrictedFromNonProtectedSetting() { + installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + eventually { assertFalse(ecm.isRestricted(APP_PACKAGE_NAME, NON_PROTECTED_SETTING)) } + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenRestrictedAppThenClearRestrictionNotAllowedByDefault() { + installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + eventually { assertFalse(ecm.isClearRestrictionAllowed(APP_PACKAGE_NAME)) } + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenRestrictedAppWhenClearRestrictionThenNotRestrictedFromProtectedSetting() { + installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST) + runWithShellPermissionIdentity { + eventually { assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) } + ecm.setClearRestrictionAllowed(APP_PACKAGE_NAME) + eventually { assertTrue(ecm.isClearRestrictionAllowed(APP_PACKAGE_NAME)) } + ecm.clearRestriction(APP_PACKAGE_NAME) + eventually { assertFalse(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) } + } + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun createRestrictedSettingDialogIntentReturnsIntent() { + installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST) + + val intent = ecm.createRestrictedSettingDialogIntent(APP_PACKAGE_NAME, PROTECTED_SETTING) + + assertNotNull(intent) + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun grantDialogBlocksRestrictedPermissionsOfSameGroupTogether() { + installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + APP_APK_NAME_LATEST + ) + val permissionAndExpectedGrantResults = + arrayOf( + GROUP_1_PERMISSION_1_RESTRICTED to false, + GROUP_1_PERMISSION_2_RESTRICTED to false + ) + + requestAppPermissionsAndAssertResult(*permissionAndExpectedGrantResults) { + click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + + requestAppPermissionsAndAssertResult( + *permissionAndExpectedGrantResults, + waitForWindowTransition = false + ) { + assertNoEcmDialogShown() + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun grantDialogBlocksRestrictedPermissionsOfDifferentGroupsIndividually() { + installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + APP_APK_NAME_LATEST + ) + val permissionAndExpectedGrantResults = + arrayOf( + GROUP_1_PERMISSION_1_RESTRICTED to false, + GROUP_2_PERMISSION_1_RESTRICTED to false + ) + + requestAppPermissionsAndAssertResult( + *permissionAndExpectedGrantResults, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) } + doAndWaitForWindowTransition { click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) } + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + + requestAppPermissionsAndAssertResult( + *permissionAndExpectedGrantResults, + waitForWindowTransition = false + ) { + assertNoEcmDialogShown() + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun grantDialogBlocksRestrictedGroupsThenRequestsUnrestrictedGroupsDespiteOutOfOrderRequest() { + installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + APP_APK_NAME_LATEST + ) + + requestAppPermissionsAndAssertResult( + GROUP_3_PERMISSION_1_UNRESTRICTED to false, + GROUP_2_PERMISSION_1_RESTRICTED to false, + GROUP_3_PERMISSION_2_UNRESTRICTED to false, + GROUP_2_PERMISSION_2_RESTRICTED to false, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) } + doAndWaitForWindowTransition { clickPermissionRequestDenyButton() } + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + + requestAppPermissionsAndAssertResult( + GROUP_3_PERMISSION_1_UNRESTRICTED to true, + GROUP_3_PERMISSION_2_UNRESTRICTED to true, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { clickPermissionRequestAllowForegroundButton() } + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun grantDialogBlocksRestrictedGroupsThenRequestsUnrestrictedHighPriorityGroups() { + installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + APP_APK_NAME_LATEST + ) + + requestAppPermissionsAndAssertResult( + GROUP_3_PERMISSION_1_UNRESTRICTED to true, + GROUP_2_PERMISSION_1_RESTRICTED to false, + GROUP_1_PERMISSION_1_RESTRICTED to false, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) } + doAndWaitForWindowTransition { click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) } + doAndWaitForWindowTransition { clickPermissionRequestAllowForegroundButton() } + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun grantDialogBlocksRestrictedGroupsThenRequestsUnrestrictedLowPriorityGroups() { + installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms( + APP_APK_NAME_LATEST + ) + + requestAppPermissionsAndAssertResult( + GROUP_4_PERMISSION_1_UNRESTRICTED to true, + GROUP_2_PERMISSION_1_RESTRICTED to false, + GROUP_1_PERMISSION_1_RESTRICTED to false, + waitForWindowTransition = false + ) { + doAndWaitForWindowTransition { click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) } + doAndWaitForWindowTransition { click(By.res(ALERT_DIALOG_OK_BUTTON), TIMEOUT_MILLIS) } + doAndWaitForWindowTransition { clickPermissionRequestAllowForegroundButton() } + } + assertTrue(isClearRestrictionAllowed(APP_PACKAGE_NAME)) + } + + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun givenPackagesSourceUnspecifiedAndInstallerTargetVersionAtLeastVThenIsRestricted() { + val installingApplicationInfo = getApplicationInfoAsUser(context, + TEST_INSTALLER_PACKAGE_NAME) + assertTrue(installingApplicationInfo.targetSdkVersion >= + Build.VERSION_CODES.VANILLA_ICE_CREAM) + + installPackageViaSession(APP_APK_NAME_LATEST) + + val installSource = packageManager.getInstallSourceInfo(APP_PACKAGE_NAME) + assertEquals(installSource.installingPackageName, TEST_INSTALLER_PACKAGE_NAME) + assertEquals(installSource.packageSource, PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED) + + runWithShellPermissionIdentity { + assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) + } + } + + private fun isClearRestrictionAllowed(packageName: String) = callWithShellPermissionIdentity { + ecm.isClearRestrictionAllowed(packageName) + } + + private fun assertNoEcmDialogShown() { + assertNull( + "expected to not see dialog", + waitFindObjectOrNull(By.res(ALERT_DIALOG_OK_BUTTON), UNEXPECTED_TIMEOUT_MILLIS.toLong()) + ) + } + + companion object { + private const val GROUP_1_PERMISSION_1_RESTRICTED = Manifest.permission.CALL_PHONE + private const val GROUP_1_PERMISSION_2_RESTRICTED = Manifest.permission.READ_PHONE_STATE + private const val GROUP_2_PERMISSION_1_RESTRICTED = Manifest.permission.SEND_SMS + private const val GROUP_2_PERMISSION_2_RESTRICTED = Manifest.permission.READ_SMS + private const val GROUP_3_PERMISSION_1_UNRESTRICTED = + Manifest.permission.ACCESS_FINE_LOCATION + private const val GROUP_3_PERMISSION_2_UNRESTRICTED = + Manifest.permission.ACCESS_COARSE_LOCATION + private const val GROUP_4_PERMISSION_1_UNRESTRICTED = Manifest.permission.BODY_SENSORS + + private const val NON_PROTECTED_SETTING = "example_setting_which_is_not_protected" + private const val PROTECTED_SETTING = "android:bind_accessibility_service" + + @Throws(PackageManager.NameNotFoundException::class) + private fun setAppEcmState( + context: Context, + appOpsManager: AppOpsManager, + packageName: String, + mode: Int + ) = + appOpsManager.setMode( + AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, + getPackageUid(context, packageName), + packageName, + mode + ) + + @Throws(PackageManager.NameNotFoundException::class) + private fun getAppEcmState( + context: Context, + appOpsManager: AppOpsManager, + packageName: String + ) = + appOpsManager.noteOpNoThrow( + AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, + getPackageUid(context, packageName), + packageName, + context.attributionTag, + /* message */ null + ) + + @Throws(PackageManager.NameNotFoundException::class) + private fun getPackageUid(context: Context, packageName: String) = + getApplicationInfoAsUser(context, packageName).uid + + @Throws(PackageManager.NameNotFoundException::class) + private fun getApplicationInfoAsUser(context: Context, packageName: String) = + packageManager.getApplicationInfoAsUser( + packageName, + /* flags */ 0, + Process.myUserHandle() + ) + } +} diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTapjackingTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTapjackingTest.kt index 3a8a6a838..b81432369 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionTapjackingTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionTapjackingTest.kt @@ -43,6 +43,9 @@ class PermissionTapjackingTest : BaseUsePermissionTest() { // PermissionController for television uses a floating window. assumeFalse(isTv) + // Automotive split-screen multitasking uses multi-window mode + assumeFalse(isAutomotiveSplitscreen) + assertAppHasPermission(ACCESS_FINE_LOCATION, false) requestAppPermissionsForNoResult(ACCESS_FINE_LOCATION) {} @@ -63,6 +66,9 @@ class PermissionTapjackingTest : BaseUsePermissionTest() { // PermissionController for television uses a floating window. assumeFalse(isTv) + // Automotive split-screen multitasking uses multi-window mode + assumeFalse(isAutomotiveSplitscreen) + assertAppHasPermission(ACCESS_FINE_LOCATION, false) requestAppPermissionsForNoResult(ACCESS_FINE_LOCATION) {} diff --git a/tests/cts/permissionui/src/android/permissionui/cts/SafetyLabelChangesJobServiceTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/SafetyLabelChangesJobServiceTest.kt index 690d76729..bb49bc3c2 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/SafetyLabelChangesJobServiceTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/SafetyLabelChangesJobServiceTest.kt @@ -101,11 +101,6 @@ class SafetyLabelChangesJobServiceTest : BaseUsePermissionTest() { SystemUtil.runShellCommand("input keyevent KEYCODE_WAKEUP") SystemUtil.runShellCommand("wm dismiss-keyguard") - // Bypass battery saving restrictions - SystemUtil.runShellCommand( - "cmd tare set-vip " + - "${Process.myUserHandle().identifier} $permissionControllerPackageName true" - ) CtsNotificationListenerServiceUtils.cancelNotifications(permissionControllerPackageName) resetPermissionControllerAndSimulateReboot() } @@ -115,11 +110,6 @@ class SafetyLabelChangesJobServiceTest : BaseUsePermissionTest() { cancelJob(SAFETY_LABEL_CHANGES_DETECT_UPDATES_JOB_ID) cancelJob(SAFETY_LABEL_CHANGES_PERIODIC_NOTIFICATION_JOB_ID) CtsNotificationListenerServiceUtils.cancelNotifications(permissionControllerPackageName) - // Reset battery saving restrictions - SystemUtil.runShellCommand( - "cmd tare set-vip " + - "${Process.myUserHandle().identifier} $permissionControllerPackageName default" - ) } @Test diff --git a/tests/cts/permissionui/src/android/permissionui/cts/SensorBlockedBannerTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/SensorBlockedBannerTest.kt index f8c7d4f51..614b59f3c 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/SensorBlockedBannerTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/SensorBlockedBannerTest.kt @@ -31,6 +31,7 @@ import androidx.test.filters.SdkSuppress import androidx.test.uiautomator.By import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity +import com.android.modules.utils.build.SdkLevel import java.util.regex.Pattern import org.junit.Assert.assertTrue import org.junit.Assume @@ -50,7 +51,6 @@ class SensorBlockedBannerTest : BaseUsePermissionTest() { private val sensorPrivacyManager = context.getSystemService(SensorPrivacyManager::class.java)!! private val locationManager = context.getSystemService(LocationManager::class.java)!! - private val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java)!! private val sensorToPermissionGroup = mapOf( @@ -122,7 +122,11 @@ class SensorBlockedBannerTest : BaseUsePermissionTest() { @Test fun testCardClickOpenPrivacyControls() { + Assume.assumeTrue(SdkLevel.isAtLeastT()) Assume.assumeTrue(sensorPrivacyManager.supportsSensorToggle(CAMERA)) + val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java) + Assume.assumeNotNull(safetyCenterManager) + var isSafetyCenterEnabled = false runWithShellPermissionIdentity { isSafetyCenterEnabled = safetyCenterManager.isSafetyCenterEnabled diff --git a/tests/cts/permissionui/src/android/permissionui/cts/StartForFutureActivity.kt b/tests/cts/permissionui/src/android/permissionui/cts/StartForFutureActivity.kt index 8caa4e6bf..f9f9e8cd2 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/StartForFutureActivity.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/StartForFutureActivity.kt @@ -21,7 +21,9 @@ import android.app.Instrumentation import android.content.Intent import android.os.Bundle import android.util.Log +import android.util.LruCache import java.util.concurrent.CompletableFuture +import java.util.concurrent.atomic.AtomicInteger class StartForFutureActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -36,26 +38,25 @@ class StartForFutureActivity : Activity() { intent: Intent, future: CompletableFuture<Instrumentation.ActivityResult> ) { - if (StartForFutureActivity.future != null) { - throw RuntimeException( - "StartForFutureActivity only supports launching one " + - "concurrent activity, but more than one was attempted." - ) - } - - startActivityForResult(intent, 1) - StartForFutureActivity.future = future + val requestCode = nextRequestCode.getAndIncrement() + futures.put(requestCode, future) + startActivityForResult(intent, requestCode) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - future!!.complete(Instrumentation.ActivityResult(resultCode, data)) - future = null + val future = + futures.remove(requestCode) + ?: throw IllegalStateException( + "StartForFutureActivity received an activity result with an unknown requestCode" + ) + future.complete(Instrumentation.ActivityResult(resultCode, data)) finish() } companion object { - private var future: CompletableFuture<Instrumentation.ActivityResult>? = null private val TAG = StartForFutureActivity::class.simpleName + private var nextRequestCode = AtomicInteger(1) + private val futures = LruCache<Int, CompletableFuture<Instrumentation.ActivityResult>>(10) } } diff --git a/tests/cts/role/Android.bp b/tests/cts/role/Android.bp index 368a45263..2a312976b 100644 --- a/tests/cts/role/Android.bp +++ b/tests/cts/role/Android.bp @@ -28,17 +28,19 @@ android_test { ], static_libs: [ + "android.permission.flags-aconfig-java", "androidx.test.rules", "compatibility-device-util-axt", "ctstestrunner-axt", - "truth", "platform-test-annotations", + "truth", ], test_suites: [ "cts", "general-tests", "mts-permission", + "mcts-permission", ], data: [ diff --git a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java index 001a761c2..11ae53186 100644 --- a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java +++ b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java @@ -27,9 +27,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import android.app.Activity; +import android.app.AppOpsManager; import android.app.Instrumentation; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; @@ -41,8 +43,13 @@ import android.content.pm.PermissionInfo; import android.os.Build; import android.os.Process; import android.os.UserHandle; +import android.permission.flags.Flags; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.provider.Telephony; +import android.telephony.TelephonyManager; import android.util.Pair; import androidx.annotation.NonNull; @@ -56,6 +63,7 @@ import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.UiObjectNotFoundException; +import androidx.test.uiautomator.Until; import com.android.compatibility.common.util.DisableAnimationRule; import com.android.compatibility.common.util.FreezeRotationRule; @@ -89,6 +97,8 @@ public class RoleManagerTest { private static final long UNEXPECTED_TIMEOUT_MILLIS = 1000; private static final String ROLE_NAME = RoleManager.ROLE_BROWSER; + private static final String ROLE_PHONE_NAME = RoleManager.ROLE_DIALER; + private static final String ROLE_SMS_NAME = RoleManager.ROLE_SMS; private static final String ROLE_SHORT_LABEL = "Browser app"; private static final String APP_APK_PATH = "/data/local/tmp/cts-role/CtsRoleTestApp.apk"; @@ -126,9 +136,15 @@ public class RoleManagerTest { private static final Context sContext = InstrumentationRegistry.getTargetContext(); private static final PackageManager sPackageManager = sContext.getPackageManager(); private static final RoleManager sRoleManager = sContext.getSystemService(RoleManager.class); + private static final boolean sIsAutomotive = sPackageManager.hasSystemFeature( + PackageManager.FEATURE_AUTOMOTIVE); + private static final boolean sIsTelevision = sPackageManager.hasSystemFeature( + PackageManager.FEATURE_TELEVISION); private static final boolean sIsWatch = sPackageManager.hasSystemFeature( PackageManager.FEATURE_WATCH); + private static final BySelector ENHANCED_CONFIRMATION_DIALOG_SELECTOR = + By.res("com.android.permissioncontroller:id/enhanced_confirmation_dialog_title"); // TODO(b/327528959): consider using resource selectors for Wear too, once the underlying // issue is handled. private static final BySelector NEGATIVE_BUTTON_SELECTOR = @@ -141,6 +157,8 @@ public class RoleManagerTest { : By.res("com.android.permissioncontroller:id/dont_ask_again"); @Rule + public CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + @Rule public DisableAnimationRule mDisableAnimationRule = new DisableAnimationRule(); @Rule @@ -231,6 +249,24 @@ public class RoleManagerTest { assertIsRoleHolder(ROLE_NAME, APP_PACKAGE_NAME, true); } + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @FlakyTest(bugId = 288468003, detail = "CtsRoleTestCases is breaching 20min SLO") + public void requestRoleThenBlockRequestRoleDialogByRestrictedSettingDialog() throws Exception { + assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_SMS)); + assumeFalse(sIsWatch || sIsAutomotive || sIsTelevision); + runWithShellPermissionIdentity( + () -> setEnhancedConfirmationRestrictedAppOpMode(sContext, APP_PACKAGE_NAME, + AppOpsManager.MODE_ERRORED)); + + requestRole(ROLE_SMS_NAME); + waitFindObject(ENHANCED_CONFIRMATION_DIALOG_SELECTOR, TIMEOUT_MILLIS); + + pressBack(); + } + @Test @FlakyTest(bugId = 288468003, detail = "CtsRoleTestCases is breaching 20min SLO") public void requestRoleFirstTimeNoDontAskAgain() throws Exception { @@ -633,6 +669,35 @@ public class RoleManagerTest { pressBack(); } + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = + "VanillaIceCream") + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @FlakyTest(bugId = 288468003, detail = "CtsRoleTestCases is breaching 20min SLO") + public void openDefaultAppDetailsOnHandHeldThenRestrictedAppIsNotSelectableAsDefaultApp() + throws Exception { + assumeTrue(sRoleManager.isRoleAvailable(RoleManager.ROLE_DIALER)); + assumeFalse(sIsWatch || sIsAutomotive || sIsTelevision); + runWithShellPermissionIdentity( + () -> setEnhancedConfirmationRestrictedAppOpMode(sContext, APP_PACKAGE_NAME, + AppOpsManager.MODE_ERRORED)); + + runWithShellPermissionIdentity(() -> sContext.startActivity(new Intent( + Intent.ACTION_MANAGE_DEFAULT_APP) + .addCategory(Intent.CATEGORY_DEFAULT) + .putExtra(Intent.EXTRA_ROLE_NAME, ROLE_PHONE_NAME) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK))); + + waitFindObject(By.text(APP_LABEL).enabled(false)).clickAndWait(Until.newWindow(), + TIMEOUT_MILLIS); + + waitFindObject(ENHANCED_CONFIRMATION_DIALOG_SELECTOR, TIMEOUT_MILLIS); + pressBack(); + + pressBack(); + } + @Test @FlakyTest(bugId = 288468003, detail = "CtsRoleTestCases is breaching 20min SLO") public void openDefaultAppDetailsAndSetDefaultAppThenIsDefaultApp() throws Exception { @@ -687,8 +752,8 @@ public class RoleManagerTest { if (sIsWatch) { waitFindObject(By.clickable(true).checked(false)).click(); } else { - waitFindObject( - By.clickable(true).hasDescendant(By.checkable(true).checked(false))).click(); + waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).enabled(true) + .checked(false))).click(); } if (sIsWatch) { @@ -714,6 +779,7 @@ public class RoleManagerTest { pressBack(); } + @FlakyTest @Test public void openDefaultAppListThenIsNotDefaultAppInList() throws Exception { sContext.startActivity(new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS) @@ -781,6 +847,15 @@ public class RoleManagerTest { pressBack(); } + private void setEnhancedConfirmationRestrictedAppOpMode(@NonNull Context context, + @NonNull String packageName, int mode) + throws PackageManager.NameNotFoundException { + AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class); + appOpsManager.setMode(AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, + context.getPackageManager().getApplicationInfo(packageName, 0).uid, + packageName, mode); + } + private static void waitForIdle() { UiAutomatorUtils.getUiDevice().waitForIdle(); } @@ -1066,6 +1141,32 @@ public class RoleManagerTest { assertThat(Telephony.Sms.getDefaultSmsPackage(sContext)).isEqualTo(APP_PACKAGE_NAME); } + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, + codeName = "VanillaIceCream") + @Test + @RequiresFlagsEnabled(Flags.FLAG_GET_EMERGENCY_ROLE_HOLDER_API_ENABLED) + public void telephonyManagerGetEmergencyAssistancePackageNameBackedByRole() throws Exception { + TelephonyManager telephonyManager = sContext.getSystemService(TelephonyManager.class); + List<String> emergencyRoleHolders = getRoleHolders(RoleManager.ROLE_EMERGENCY); + + if (telephonyManager.isVoiceCapable() + && callWithShellPermissionIdentity(() -> + telephonyManager.isEmergencyAssistanceEnabled())) { + String emergencyAssistancePackageName = callWithShellPermissionIdentity(() -> + telephonyManager.getEmergencyAssistancePackageName()); + if (emergencyRoleHolders.isEmpty()) { + assertThat(emergencyAssistancePackageName).isNull(); + } else { + assertThat(emergencyRoleHolders).hasSize(1); + assertThat(emergencyAssistancePackageName).isEqualTo(emergencyRoleHolders.get(0)); + } + } else { + assertThrows(IllegalStateException.class, () -> + callWithShellPermissionIdentity(() -> + telephonyManager.getEmergencyAssistancePackageName())); + } + } + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S, codeName = "S") @Test public void cannotBypassRoleQualificationWithoutPermission() throws Exception { diff --git a/tests/cts/safetycenter/Android.bp b/tests/cts/safetycenter/Android.bp index 6e0fedec0..e49587c39 100644 --- a/tests/cts/safetycenter/Android.bp +++ b/tests/cts/safetycenter/Android.bp @@ -48,5 +48,6 @@ android_test { "cts", "general-tests", "mts-permission", + "mcts-permission", ], } diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourceTest.kt b/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourceTest.kt index 59cc6547a..4b6f0f6f9 100644 --- a/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourceTest.kt +++ b/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourceTest.kt @@ -18,11 +18,14 @@ package android.safetycenter.cts.config import android.content.res.Resources import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE +import android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM +import android.platform.test.annotations.RequiresFlagsEnabled import android.safetycenter.config.SafetySource import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.truth.os.ParcelableSubject.assertThat import androidx.test.filters.SdkSuppress import com.android.modules.utils.build.SdkLevel +import com.android.permission.flags.Flags import com.android.safetycenter.testing.EqualsHashCodeToStringTester import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertThrows @@ -126,6 +129,35 @@ class SafetySourceTest { } } + @RequiresFlagsEnabled(Flags.FLAG_PRIVATE_PROFILE_TITLE_API) + @SdkSuppress(minSdkVersion = VANILLA_ICE_CREAM, codeName = "VanillaIceCream") + @Test + fun getTitleForPrivateProfileResId_returnsTitleForPrivateProfileResIdOrThrows() { + if (!Flags.privateProfileTitleApi()) { + return + } + assertThrows(UnsupportedOperationException::class.java) { + DYNAMIC_BAREBONE.titleForPrivateProfileResId + } + assertThat(dynamicAllOptional().titleForPrivateProfileResId).isEqualTo(REFERENCE_RES_ID) + assertThrows(UnsupportedOperationException::class.java) { + DYNAMIC_DISABLED.titleForPrivateProfileResId + } + assertThat(DYNAMIC_HIDDEN.titleForPrivateProfileResId).isEqualTo(Resources.ID_NULL) + assertThat(DYNAMIC_HIDDEN_WITH_SEARCH.titleForPrivateProfileResId) + .isEqualTo(REFERENCE_RES_ID) + assertThrows(UnsupportedOperationException::class.java) { + STATIC_BAREBONE.titleForPrivateProfileResId + } + assertThat(STATIC_ALL_OPTIONAL.titleForPrivateProfileResId).isEqualTo(REFERENCE_RES_ID) + assertThrows(UnsupportedOperationException::class.java) { + ISSUE_ONLY_BAREBONE.titleForPrivateProfileResId + } + assertThrows(UnsupportedOperationException::class.java) { + issueOnlyAllOptional().titleForPrivateProfileResId + } + } + @Test fun getSummaryResId_returnsSummaryResIdOrThrows() { assertThat(DYNAMIC_BAREBONE.summaryResId).isEqualTo(REFERENCE_RES_ID) @@ -360,6 +392,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -390,6 +425,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -413,6 +451,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -436,6 +477,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -459,6 +503,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -482,6 +529,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -505,6 +555,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -536,6 +589,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -559,6 +615,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -582,6 +641,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -605,6 +667,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -628,6 +693,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() ) @@ -650,6 +718,11 @@ class SafetySourceTest { .setNotificationsAllowed(false) .setDeduplicationGroup(DEDUPLICATION_GROUP) .addPackageCertificateHash(HASH1) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } + } .build() ) addEqualityGroup( @@ -669,6 +742,11 @@ class SafetySourceTest { .setNotificationsAllowed(true) .setDeduplicationGroup("other_deduplication_group") .addPackageCertificateHash(HASH1) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } + } .build() ) // With no package cert hashes provided @@ -688,6 +766,11 @@ class SafetySourceTest { .setRefreshOnPageOpenAllowed(true) .setNotificationsAllowed(true) .setDeduplicationGroup(DEDUPLICATION_GROUP) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } + } .build() ) // With longer package cert hash list @@ -709,6 +792,11 @@ class SafetySourceTest { .setDeduplicationGroup(DEDUPLICATION_GROUP) .addPackageCertificateHash(HASH1) .addPackageCertificateHash(HASH2) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } + } .build() ) // With package cert hash list with different value @@ -729,6 +817,11 @@ class SafetySourceTest { .setNotificationsAllowed(true) .setDeduplicationGroup(DEDUPLICATION_GROUP) .addPackageCertificateHash(HASH2) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } + } .build() ) } @@ -785,6 +878,9 @@ class SafetySourceTest { setDeduplicationGroup(DEDUPLICATION_GROUP) addPackageCertificateHash(HASH1) } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } } .build() @@ -817,6 +913,11 @@ class SafetySourceTest { .setProfile(SafetySource.PROFILE_ALL) .setInitialDisplayState(SafetySource.INITIAL_DISPLAY_STATE_HIDDEN) .setSearchTermsResId(REFERENCE_RES_ID) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } + } .build() internal val STATIC_BAREBONE = @@ -837,6 +938,11 @@ class SafetySourceTest { .setIntentAction(INTENT_ACTION) .setProfile(SafetySource.PROFILE_ALL) .setSearchTermsResId(REFERENCE_RES_ID) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(REFERENCE_RES_ID) + } + } .build() internal val ISSUE_ONLY_BAREBONE = diff --git a/tests/functional/safetycenter/multiusers/Android.bp b/tests/functional/safetycenter/multiusers/Android.bp index b5caf48e6..2f1cda9ed 100644 --- a/tests/functional/safetycenter/multiusers/Android.bp +++ b/tests/functional/safetycenter/multiusers/Android.bp @@ -36,6 +36,7 @@ android_test { "Harrier", "Nene", "TestApp", + "permissions-aconfig-flags-lib", ], test_suites: [ "general-tests", diff --git a/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt b/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt index acbc5cfc0..8a54ccf26 100644 --- a/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt +++ b/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt @@ -21,6 +21,8 @@ import android.Manifest.permission.INTERACT_ACROSS_USERS_FULL import android.app.PendingIntent import android.content.Context import android.os.UserHandle +import android.platform.test.annotations.RequiresFlagsDisabled +import android.platform.test.annotations.RequiresFlagsEnabled import android.safetycenter.SafetyCenterData import android.safetycenter.SafetyCenterEntry import android.safetycenter.SafetyCenterEntry.ENTRY_SEVERITY_LEVEL_CRITICAL_WARNING @@ -43,6 +45,7 @@ import com.android.bedstead.harrier.DeviceState import com.android.bedstead.harrier.annotations.EnsureHasAdditionalUser import com.android.bedstead.harrier.annotations.EnsureHasCloneProfile import com.android.bedstead.harrier.annotations.EnsureHasNoWorkProfile +import com.android.bedstead.harrier.annotations.EnsureHasPrivateProfile import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile import com.android.bedstead.harrier.annotations.enterprise.EnsureHasDeviceOwner import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoDeviceOwner @@ -227,6 +230,13 @@ class SafetyCenterMultiUsersTest { .setEnabled(false) .build() + private val dynamicDisabledForPrivateUpdated: SafetyCenterEntry + get() = + safetyCenterEntryOkForPrivate(DYNAMIC_DISABLED_ID, deviceState.privateProfile().id()) + + private val dynamicHiddenForPrivateUpdated: SafetyCenterEntry + get() = safetyCenterEntryOkForPrivate(DYNAMIC_HIDDEN_ID, deviceState.privateProfile().id()) + private val staticGroupBuilder = SafetyCenterEntryGroup.Builder(STATIC_GROUP_ID, "OK") .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNSPECIFIED) @@ -267,6 +277,24 @@ class SafetyCenterMultiUsersTest { .setEnabled(false) .build() + private val staticAllOptionalForPrivateBuilder + get() = + safetyCenterTestData + .safetyCenterEntryDefaultStaticBuilder( + STATIC_ALL_OPTIONAL_ID, + userId = deviceState.privateProfile().id(), + title = "Unknown" + ) + .setPendingIntent( + createTestActivityRedirectPendingIntentForUser( + deviceState.privateProfile().userHandle(), + explicit = false + ) + ) + + private val staticAllOptionalForPrivate + get() = staticAllOptionalForPrivateBuilder.build() + private fun createStaticEntry(explicit: Boolean = true): SafetyCenterStaticEntry = SafetyCenterStaticEntry.Builder("OK") .setSummary("OK") @@ -292,9 +320,25 @@ class SafetyCenterMultiUsersTest { ) ) + private fun staticEntryForPrivateBuilder( + title: CharSequence = "Unknown", + explicit: Boolean = true + ) = + SafetyCenterStaticEntry.Builder(title) + .setSummary("OK") + .setPendingIntent( + createTestActivityRedirectPendingIntentForUser( + deviceState.privateProfile().userHandle(), + explicit + ) + ) + private fun createStaticEntryForWork(explicit: Boolean = true): SafetyCenterStaticEntry = staticEntryForWorkBuilder(explicit = explicit).build() + private fun createStaticEntryForPrivate(explicit: Boolean = true): SafetyCenterStaticEntry = + staticEntryForPrivateBuilder(explicit = explicit).build() + private fun createStaticEntryForWorkPaused(): SafetyCenterStaticEntry = staticEntryForWorkBuilder(explicit = false) .setSummary(safetyCenterResourcesApk.getStringByName("work_profile_paused")) @@ -313,6 +357,13 @@ class SafetyCenterMultiUsersTest { .setPendingIntent(safetySourceTestData.createTestActivityRedirectPendingIntent()) .build() + private val staticEntryForPrivateUpdated: SafetyCenterStaticEntry + get() = + SafetyCenterStaticEntry.Builder("Unspecified title for Private") + .setSummary("Unspecified summary") + .setPendingIntent(safetySourceTestData.createTestActivityRedirectPendingIntent()) + .build() + private val safetyCenterDataForAdditionalUser get() = SafetyCenterData( @@ -657,7 +708,7 @@ class SafetyCenterMultiUsersTest { @Test @EnsureHasWorkProfile(installInstrumentedApp = TRUE) - fun getSafetyCenterData_withComplexConfigWithAllDataProvided_returnsAllDataProvided() { + fun getSafetyCenterData_withComplexConfigWithExtraWorkOnlyWithAllDataProvided_returnsAllDataProvided() { safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexAllProfileConfig) updatePrimaryProfileSources() updateWorkProfileSources() @@ -765,6 +816,267 @@ class SafetyCenterMultiUsersTest { } @Test + @RequiresFlagsDisabled(com.android.permission.flags.Flags.FLAG_PRIVATE_PROFILE_SUPPORTED) + @EnsureHasWorkProfile(installInstrumentedApp = TRUE) + @EnsureHasPrivateProfile(installInstrumentedApp = TRUE) + fun getSafetyCenterData_withComplexConfigWithPrivateProfileDisallowedWithAllDataProvided_returnsAllDataProvided() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexAllProfileConfig) + updatePrimaryProfileSources() + updateWorkProfileSources() + updatePrivateProfileSources() + + val apiSafetyCenterData = safetyCenterManager.getSafetyCenterDataWithPermission() + + val managedUserId = deviceState.workProfile().id() + val safetyCenterDataFromComplexConfig = + SafetyCenterData( + safetyCenterTestData.safetyCenterStatusCritical(11), + listOf( + safetyCenterTestData.safetyCenterIssueCritical( + DYNAMIC_BAREBONE_ID, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueCritical( + ISSUE_ONLY_BAREBONE_ID, + attributionTitle = null, + groupId = ISSUE_ONLY_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueRecommendation( + DYNAMIC_DISABLED_ID, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueRecommendation( + ISSUE_ONLY_ALL_OPTIONAL_ID, + attributionTitle = null, + groupId = ISSUE_ONLY_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_IN_STATELESS_ID, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_IN_STATELESS_ID, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_DISABLED_ID, + managedUserId, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_HIDDEN_ID, + managedUserId, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_ALL_OPTIONAL_ID, + managedUserId, + attributionTitle = null, + groupId = ISSUE_ONLY_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_IN_STATELESS_ID, + managedUserId, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_IN_STATELESS_ID, + managedUserId, + groupId = MIXED_STATELESS_GROUP_ID + ) + ), + listOf( + SafetyCenterEntryOrGroup( + SafetyCenterEntryGroup.Builder(DYNAMIC_GROUP_ID, "OK") + .setSeverityLevel(ENTRY_SEVERITY_LEVEL_CRITICAL_WARNING) + .setSummary("Critical summary") + .setEntries( + listOf( + dynamicBareboneUpdated, + dynamicDisabledUpdated, + dynamicDisabledForWorkUpdated, + dynamicHiddenUpdated, + dynamicHiddenForWorkUpdated + ) + ) + .setSeverityUnspecifiedIconType( + SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION + ) + .build() + ), + SafetyCenterEntryOrGroup( + staticGroupBuilder + .setEntries( + listOf(staticBarebone, staticAllOptional, staticAllOptionalForWork) + ) + .build() + ) + ), + listOf( + SafetyCenterStaticEntryGroup( + "OK", + listOf( + staticEntryUpdated, + staticEntryForWorkUpdated, + createStaticEntry(explicit = false), + createStaticEntryForWork(explicit = false) + ) + ) + ) + ) + assertThat(apiSafetyCenterData.withoutExtras()).isEqualTo(safetyCenterDataFromComplexConfig) + } + + // TODO(b/286539356) add the os feature flag requirement when available. + @Test + @RequiresFlagsEnabled(com.android.permission.flags.Flags.FLAG_PRIVATE_PROFILE_SUPPORTED) + @EnsureHasWorkProfile(installInstrumentedApp = TRUE) + @EnsureHasPrivateProfile(installInstrumentedApp = TRUE) + fun getSafetyCenterData_withComplexConfigWithAllDataProvided_returnsAllDataProvided() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexAllProfileConfig) + updatePrimaryProfileSources() + updateWorkProfileSources() + updatePrivateProfileSources() + + val apiSafetyCenterData = safetyCenterManager.getSafetyCenterDataWithPermission() + + val managedUserId = deviceState.workProfile().id() + val privateProfileId = deviceState.privateProfile().id() + val safetyCenterDataFromComplexConfig = + SafetyCenterData( + safetyCenterTestData.safetyCenterStatusCritical(11), + listOf( + safetyCenterTestData.safetyCenterIssueCritical( + DYNAMIC_BAREBONE_ID, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueCritical( + ISSUE_ONLY_BAREBONE_ID, + attributionTitle = null, + groupId = ISSUE_ONLY_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueRecommendation( + DYNAMIC_DISABLED_ID, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueRecommendation( + ISSUE_ONLY_ALL_OPTIONAL_ID, + attributionTitle = null, + groupId = ISSUE_ONLY_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_IN_STATELESS_ID, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_IN_STATELESS_ID, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_DISABLED_ID, + managedUserId, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_HIDDEN_ID, + managedUserId, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_ALL_OPTIONAL_ID, + managedUserId, + attributionTitle = null, + groupId = ISSUE_ONLY_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_IN_STATELESS_ID, + managedUserId, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_IN_STATELESS_ID, + managedUserId, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_DISABLED_ID, + privateProfileId, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_HIDDEN_ID, + privateProfileId, + groupId = DYNAMIC_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_ALL_OPTIONAL_ID, + privateProfileId, + attributionTitle = null, + groupId = ISSUE_ONLY_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + DYNAMIC_IN_STATELESS_ID, + privateProfileId, + groupId = MIXED_STATELESS_GROUP_ID + ), + safetyCenterTestData.safetyCenterIssueInformation( + ISSUE_ONLY_IN_STATELESS_ID, + privateProfileId, + groupId = MIXED_STATELESS_GROUP_ID + ) + ), + listOf( + SafetyCenterEntryOrGroup( + SafetyCenterEntryGroup.Builder(DYNAMIC_GROUP_ID, "OK") + .setSeverityLevel(ENTRY_SEVERITY_LEVEL_CRITICAL_WARNING) + .setSummary("Critical summary") + .setEntries( + listOf( + dynamicBareboneUpdated, + dynamicDisabledUpdated, + dynamicDisabledForWorkUpdated, + dynamicDisabledForPrivateUpdated, + dynamicHiddenUpdated, + dynamicHiddenForWorkUpdated, + dynamicHiddenForPrivateUpdated + ) + ) + .setSeverityUnspecifiedIconType( + SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION + ) + .build() + ), + SafetyCenterEntryOrGroup( + staticGroupBuilder + .setEntries( + listOf( + staticBarebone, + staticAllOptional, + staticAllOptionalForWork, + staticAllOptionalForPrivate + ) + ) + .build() + ) + ), + listOf( + SafetyCenterStaticEntryGroup( + "OK", + listOf( + staticEntryUpdated, + staticEntryForWorkUpdated, + staticEntryForPrivateUpdated, + createStaticEntry(explicit = false), + createStaticEntryForWork(explicit = false), + createStaticEntryForPrivate(explicit = false) + ) + ) + ) + ) + assertThat(apiSafetyCenterData.withoutExtras()).isEqualTo(safetyCenterDataFromComplexConfig) + } + + @Test @EnsureHasWorkProfile(installInstrumentedApp = TRUE) fun getSafetyCenterData_withQuietMode_shouldHaveWorkProfilePausedSummaryAndNoWorkIssues() { safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexAllProfileConfig) @@ -920,6 +1232,77 @@ class SafetyCenterMultiUsersTest { } @Test + @RequiresFlagsEnabled(com.android.permission.flags.Flags.FLAG_PRIVATE_PROFILE_SUPPORTED) + @EnsureHasPrivateProfile(installInstrumentedApp = TRUE) + fun getSafetyCenterData_afterPrivateProfileRemoved_returnsDefaultData() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceAllProfileConfig) + val privateSafetyCenterManager = + getSafetyCenterManagerForUser(deviceState.privateProfile().userHandle()) + val safetyCenterDataWithPrivateProfile = + SafetyCenterData( + safetyCenterTestData.safetyCenterStatusUnknown, + emptyList(), + listOf( + SafetyCenterEntryOrGroup( + SafetyCenterEntryGroup.Builder(SINGLE_SOURCE_GROUP_ID, "OK") + .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNKNOWN) + .setSummary( + safetyCenterResourcesApk.getStringByName("group_unknown_summary") + ) + .setEntries( + listOf( + safetyCenterTestData.safetyCenterEntryDefault( + SINGLE_SOURCE_ALL_PROFILE_ID + ), + safetyCenterTestData.safetyCenterEntryDefault( + SINGLE_SOURCE_ALL_PROFILE_ID, + deviceState.privateProfile().id(), + title = "Unknown", + pendingIntent = + createTestActivityRedirectPendingIntentForUser( + deviceState.privateProfile().userHandle() + ) + ) + ) + ) + .setSeverityUnspecifiedIconType( + SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION + ) + .build() + ) + ), + emptyList() + ) + + assertThat(safetyCenterManager.getSafetyCenterDataWithPermission()) + .isEqualTo(safetyCenterDataWithPrivateProfile) + assertThat( + privateSafetyCenterManager.getSafetyCenterDataWithInteractAcrossUsersPermission() + ) + .isEqualTo(safetyCenterDataWithPrivateProfile) + + deviceState.privateProfile().remove() + + val safetyCenterDataForPrimaryUser = + SafetyCenterData( + safetyCenterTestData.safetyCenterStatusUnknown, + emptyList(), + listOf( + SafetyCenterEntryOrGroup( + safetyCenterTestData.safetyCenterEntryDefault(SINGLE_SOURCE_ALL_PROFILE_ID) + ) + ), + emptyList() + ) + assertThat(safetyCenterManager.getSafetyCenterDataWithPermission()) + .isEqualTo(safetyCenterDataForPrimaryUser) + assertThat( + privateSafetyCenterManager.getSafetyCenterDataWithInteractAcrossUsersPermission() + ) + .isEqualTo(SafetyCenterTestData.DEFAULT) + } + + @Test @EnsureHasAdditionalUser(installInstrumentedApp = TRUE) fun getSafetyCenterData_afterAdditionalUserRemoved_returnsDefaultData() { safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceAllProfileConfig) @@ -1290,6 +1673,11 @@ class SafetyCenterMultiUsersTest { .safetyCenterEntryOkBuilder(sourceId, managedUserId, title = "Ok title for Work") .build() + private fun safetyCenterEntryOkForPrivate(sourceId: String, managedUserId: Int) = + safetyCenterTestData + .safetyCenterEntryOkBuilder(sourceId, managedUserId, title = "Ok title for Private") + .build() + private fun updatePrimaryProfileSources() { safetyCenterTestHelper.setData( DYNAMIC_BAREBONE_ID, @@ -1342,4 +1730,29 @@ class SafetyCenterMultiUsersTest { SafetySourceTestData.issuesOnly(safetySourceTestData.informationIssue) ) } + + private fun updatePrivateProfileSources() { + val privateSafetyCenterManager = + getSafetyCenterManagerForUser(deviceState.privateProfile().userHandle()) + privateSafetyCenterManager.setSafetySourceDataWithInteractAcrossUsersPermission( + DYNAMIC_DISABLED_ID, + safetySourceTestData.informationWithIssueForPrivate + ) + privateSafetyCenterManager.setSafetySourceDataWithInteractAcrossUsersPermission( + DYNAMIC_HIDDEN_ID, + safetySourceTestData.informationWithIssueForPrivate + ) + privateSafetyCenterManager.setSafetySourceDataWithInteractAcrossUsersPermission( + ISSUE_ONLY_ALL_OPTIONAL_ID, + SafetySourceTestData.issuesOnly(safetySourceTestData.informationIssue) + ) + privateSafetyCenterManager.setSafetySourceDataWithInteractAcrossUsersPermission( + DYNAMIC_IN_STATELESS_ID, + safetySourceTestData.unspecifiedWithIssueForPrivate + ) + privateSafetyCenterManager.setSafetySourceDataWithInteractAcrossUsersPermission( + ISSUE_ONLY_IN_STATELESS_ID, + SafetySourceTestData.issuesOnly(safetySourceTestData.informationIssue) + ) + } } diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt index 963c593cd..4f06c0f3f 100644 --- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt +++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt @@ -3796,6 +3796,17 @@ class SafetyCenterManagerTest { assertThat(lastUpdated[key]).isNotNull() } + @Test + fun setSafetySourceData_dynamicHiddenWithIssueOnlyData_allowed() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.hiddenSourceConfig) + val expectedData = SafetySourceTestData.issuesOnly(safetySourceTestData.informationIssue) + + safetyCenterTestHelper.setData(DYNAMIC_HIDDEN_ID, expectedData) + + val actualData = safetyCenterManager.getSafetySourceDataWithPermission(DYNAMIC_HIDDEN_ID) + assertThat(actualData).isEqualTo(expectedData) + } + private fun dumpLastUpdated(): Map<String, String> { val dump = SystemUtil.runShellCommand("dumpsys safety_center data") return dump @@ -3825,9 +3836,9 @@ class SafetyCenterManagerTest { companion object { private val RESURFACE_DELAY = Duration.ofMillis(500) - // Wait 1.5 times the RESURFACE_DELAY before asserting whether an issue has or has not + // Wait 3 times the RESURFACE_DELAY before asserting whether an issue has or has not // resurfaced. Use a constant additive error buffer if we increase the delay considerably. - private val RESURFACE_TIMEOUT = RESURFACE_DELAY.multipliedBy(3).dividedBy(2) + private val RESURFACE_TIMEOUT = RESURFACE_DELAY.multipliedBy(3) // Check more than once during a RESURFACE_DELAY before asserting whether an issue has or // has not resurfaced. Use a different check logic (focused at the expected resurface time) // if we increase the delay considerably. diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt index 9c9e9b009..1678ccced 100644 --- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt +++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt @@ -44,7 +44,6 @@ import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.dis import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.reportSafetySourceErrorWithPermission import com.android.safetycenter.testing.SafetyCenterFlags import com.android.safetycenter.testing.SafetyCenterTestConfigs -import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_1 import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_2 import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_5 @@ -68,6 +67,7 @@ import kotlinx.coroutines.TimeoutCancellationException import org.junit.Before import org.junit.Rule import org.junit.Test +import org.junit.rules.TestName import org.junit.runner.RunWith /** Notification-related tests for [SafetyCenterManager]. */ @@ -81,6 +81,7 @@ class SafetyCenterNotificationTest { requireNotNull(context.getSystemService(SafetyCenterManager::class.java)) { "Could not get SafetyCenterManager" } + private var uniqueSafetySourceId: String = "" @get:Rule(order = 1) val supportsSafetyCenterRule = SupportsSafetyCenterRule(context) @get:Rule(order = 2) @@ -88,17 +89,23 @@ class SafetyCenterNotificationTest { SafetyCenterTestRule(safetyCenterTestHelper, withNotifications = true) @get:Rule(order = 3) val disableAnimationRule = DisableAnimationRule() @get:Rule(order = 4) val freezeRotationRule = FreezeRotationRule() + @get:Rule(order = 5) val testNameRule = TestName() @Before fun enableNotificationsForTestSourceBeforeTest() { SafetyCenterFlags.notificationsEnabled = true - setFlagsForImmediateNotifications(SINGLE_SOURCE_ID) - safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig) + uniqueSafetySourceId = testNameRule.methodName + setFlagsForImmediateNotifications(uniqueSafetySourceId) + safetyCenterTestHelper.setConfig( + safetyCenterTestConfigs.singleSourceConfig( + safetyCenterTestConfigs.dynamicSafetySourceBuilder(uniqueSafetySourceId).build() + ) + ) } @Test fun setSafetySourceData_withNoIssue_noNotification() { - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.information) + safetyCenterTestHelper.setData(uniqueSafetySourceId, safetySourceTestData.information) TestNotificationListener.waitForZeroNotifications() } @@ -108,7 +115,7 @@ class SafetyCenterNotificationTest { SafetyCenterFlags.immediateNotificationBehaviorIssues = emptySet() safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, safetySourceTestData.recommendationWithAccountIssue ) @@ -120,7 +127,7 @@ class SafetyCenterNotificationTest { SafetyCenterFlags.notificationsAllowedSources = emptySet() safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, safetySourceTestData.recommendationWithAccountIssue ) @@ -132,7 +139,7 @@ class SafetyCenterNotificationTest { SafetyCenterFlags.notificationsEnabled = false safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, safetySourceTestData.recommendationWithAccountIssue ) @@ -153,7 +160,7 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForZeroNotifications() } @@ -173,7 +180,7 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForZeroNotifications() } @@ -204,7 +211,7 @@ class SafetyCenterNotificationTest { .addIssue(neverNotifyIssue) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data1) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data1) TestNotificationListener.waitForZeroNotifications() SafetyCenterFlags.notificationsMinDelay = TIMEOUT_SHORT @@ -212,13 +219,14 @@ class SafetyCenterNotificationTest { // Sending new data causes Safety Center to recompute which issues to send notifications // about and this should now include the delayed issue sent in data1 above. Thread.sleep(TIMEOUT_SHORT.toMillis()) - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data2) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data2) TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Notify later", text = "This is not urgent.", - actions = listOf("See issue") + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, ) ) } @@ -239,13 +247,14 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Notify immediately", text = "This is urgent!", - actions = listOf("See issue") + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, ) ) } @@ -267,29 +276,31 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Notify immediately", text = "This is urgent!", - actions = listOf("See issue") + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, ) ) } @Test fun setSafetySourceData_withNotificationsAllowedForSourceByFlag_sendsNotification() { - SafetyCenterFlags.notificationsAllowedSources = setOf(SINGLE_SOURCE_ID) + SafetyCenterFlags.notificationsAllowedSources = setOf(uniqueSafetySourceId) val data = safetySourceTestData.recommendationWithAccountIssue - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Recommendation issue title", text = "Recommendation issue summary", - actions = listOf("See issue") + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, ) ) } @@ -316,13 +327,14 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Recommendation issue title", text = "Recommendation issue summary", - actions = listOf("Action 1", "Action 2") + actions = listOf("Action 1", "Action 2"), + safetySourceId = uniqueSafetySourceId, ) ) } @@ -355,7 +367,12 @@ class SafetyCenterNotificationTest { safetyCenterTestHelper.setData("MyNotifiableSource", data) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = "MyNotifiableSource", + ) + ) } @Test @@ -393,13 +410,14 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Custom title", text = "Custom text", - actions = listOf("Custom action 1", "Custom action 2") + actions = listOf("Custom action 1", "Custom action 2"), + safetySourceId = uniqueSafetySourceId, ) ) } @@ -431,13 +449,14 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Custom title", text = "Custom text", - actions = emptyList() + actions = emptyList(), + safetySourceId = uniqueSafetySourceId, ) ) } @@ -454,14 +473,15 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data1) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data1) val initialNotification = TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Initial", text = "Blah", - actions = listOf("See issue") + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, ) ) @@ -485,14 +505,15 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data2) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data2) val revisedNotification = TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Revised", text = "Different", - actions = listOf("See issue", "New action") + actions = listOf("See issue", "New action"), + safetySourceId = uniqueSafetySourceId, ) ) assertThat(initialNotification.statusBarNotification.key) @@ -503,11 +524,16 @@ class SafetyCenterNotificationTest { fun setSafetySourceData_twiceWithExactSameIssue_doNotNotifyTwice() { val data = safetySourceTestData.recommendationWithAccountIssue - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) TestNotificationListener.waitForZeroNotificationEvents() } @@ -517,11 +543,16 @@ class SafetyCenterNotificationTest { val data1 = safetySourceTestData.recommendationWithAccountIssue val data2 = safetySourceTestData.information - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data1) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data1) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data2) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data2) TestNotificationListener.waitForZeroNotifications() } @@ -532,12 +563,17 @@ class SafetyCenterNotificationTest { val data1 = safetySourceTestData.recommendationWithAccountIssue val data2 = safetySourceTestData.information - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data1) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data1) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) SafetyCenterFlags.notificationsEnabled = false - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data2) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data2) TestNotificationListener.waitForZeroNotificationEvents() } @@ -550,11 +586,16 @@ class SafetyCenterNotificationTest { SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build() ) - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) - safetyCenterManager.reportSafetySourceErrorWithPermission(SINGLE_SOURCE_ID, error) + safetyCenterManager.reportSafetySourceErrorWithPermission(uniqueSafetySourceId, error) TestNotificationListener.waitForZeroNotifications() } @@ -584,20 +625,21 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data1) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data1) val notificationWithChannel = TestNotificationListener.waitForSingleNotificationMatching( NotificationCharacteristics( title = "Initial", text = "Blah", - actions = listOf("See issue") + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, ) ) TestNotificationListener.cancelAndWait(notificationWithChannel.statusBarNotification.key) - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data2) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data2) TestNotificationListener.waitForZeroNotifications() } @@ -623,13 +665,24 @@ class SafetyCenterNotificationTest { .build() ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data1) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + safetyCenterTestHelper.setData(uniqueSafetySourceId, data1) + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) TestNotificationListener.cancelAndWait(notificationWithChannel.statusBarNotification.key) - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data2) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data2) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) } @Test @@ -658,6 +711,7 @@ class SafetyCenterNotificationTest { "Critical issue title", "Critical issue summary", actions = listOf("Solve issue"), + safetySourceId = SOURCE_ID_5, ) ) } @@ -677,7 +731,13 @@ class SafetyCenterNotificationTest { ) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = SOURCE_ID_1, + ) + ) TestNotificationListener.cancelAndWait(notificationWithChannel.statusBarNotification.key) @@ -693,13 +753,17 @@ class SafetyCenterNotificationTest { "Critical issue title", "Critical issue summary", actions = listOf("Solve issue"), + safetySourceId = SOURCE_ID_5, ) ) } @Test fun setSafetySourceData_withInformationIssue_lowImportanceBlockableNotification() { - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue) + safetyCenterTestHelper.setData( + uniqueSafetySourceId, + safetySourceTestData.informationWithIssue + ) TestNotificationListener.waitForNotificationsMatching( NotificationCharacteristics( @@ -707,7 +771,8 @@ class SafetyCenterNotificationTest { "Information issue summary", actions = listOf("Review"), importance = NotificationManager.IMPORTANCE_LOW, - blockable = true + blockable = true, + safetySourceId = uniqueSafetySourceId, ) ) } @@ -715,7 +780,7 @@ class SafetyCenterNotificationTest { @Test fun setSafetySourceData_withRecommendationIssue_defaultImportanceUnblockableNotification() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, safetySourceTestData.recommendationWithAccountIssue ) @@ -725,7 +790,8 @@ class SafetyCenterNotificationTest { "Recommendation issue summary", importance = NotificationManager.IMPORTANCE_DEFAULT, actions = listOf("See issue"), - blockable = false + blockable = false, + safetySourceId = uniqueSafetySourceId, ) ) } @@ -733,8 +799,8 @@ class SafetyCenterNotificationTest { @Test fun setSafetySourceData_withCriticalIssue_highImportanceUnblockableNotification() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingDeviceIssue + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingDeviceIssue(sourceId = uniqueSafetySourceId) ) TestNotificationListener.waitForNotificationsMatching( @@ -743,7 +809,8 @@ class SafetyCenterNotificationTest { "Critical issue summary", actions = listOf("Solve issue"), importance = NotificationManager.IMPORTANCE_HIGH, - blockable = false + blockable = false, + safetySourceId = uniqueSafetySourceId, ) ) } @@ -751,15 +818,20 @@ class SafetyCenterNotificationTest { @Test fun dismissSafetyCenterIssue_dismissesNotification() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, safetySourceTestData.recommendationWithAccountIssue ) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) safetyCenterManager.dismissSafetyCenterIssueWithPermission( SafetyCenterTestData.issueId( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, SafetySourceTestData.RECOMMENDATION_ISSUE_ID ) ) @@ -770,14 +842,20 @@ class SafetyCenterNotificationTest { @Test fun dismissingNotification_doesNotUpdateSafetyCenterData() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingGeneralIssue + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingGeneralIssue(sourceId = uniqueSafetySourceId) ) // Add the listener after setting the initial data so that we don't need to consume/receive // an update for that val listener = safetyCenterTestHelper.addListener() - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) TestNotificationListener.cancelAndWait(notificationWithChannel.statusBarNotification.key) @@ -813,6 +891,7 @@ class SafetyCenterNotificationTest { "Critical issue title", "Critical issue summary", actions = listOf("Solve issue"), + safetySourceId = SOURCE_ID_1, ) ) @@ -829,9 +908,14 @@ class SafetyCenterNotificationTest { fun clearSafetySourceData_cancelsAllNotifications() { val data = safetySourceTestData.recommendationWithAccountIssue - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) safetyCenterManager.clearAllSafetySourceDataForTestsWithPermission() @@ -841,15 +925,21 @@ class SafetyCenterNotificationTest { @Test fun sendActionPendingIntent_successful_updatesListener() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingGeneralIssue + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingGeneralIssue(sourceId = uniqueSafetySourceId) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } SafetySourceReceiver.setResponse( - Request.ResolveAction(SINGLE_SOURCE_ID), + Request.ResolveAction(uniqueSafetySourceId), Response.SetData(safetySourceTestData.information) ) val listener = safetyCenterTestHelper.addListener() @@ -867,15 +957,21 @@ class SafetyCenterNotificationTest { @Test fun sendActionPendingIntent_successfulNoSuccessMessage_removesNotification() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingGeneralIssue + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingGeneralIssue(sourceId = uniqueSafetySourceId) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } SafetySourceReceiver.setResponse( - Request.ResolveAction(SINGLE_SOURCE_ID), + Request.ResolveAction(uniqueSafetySourceId), Response.SetData(safetySourceTestData.information) ) @@ -887,40 +983,61 @@ class SafetyCenterNotificationTest { @Test fun sendActionPendingIntent_successfulWithSuccessMessage_successNotification() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage( + sourceId = uniqueSafetySourceId + ) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } SafetySourceReceiver.setResponse( - Request.ResolveAction(SINGLE_SOURCE_ID), + Request.ResolveAction(uniqueSafetySourceId), Response.SetData(safetySourceTestData.information) ) sendActionPendingIntentAndWaitWithPermission(action) - TestNotificationListener.waitForSuccessNotification("Issue solved") + TestNotificationListener.waitForSuccessNotification("Issue solved") { + assertThat(NotificationCharacteristics.safetySourceIdMatches(it, uniqueSafetySourceId)) + .isTrue() + } } @Test fun successNotification_notificationHasAutoCancel() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage( + sourceId = uniqueSafetySourceId + ) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } SafetySourceReceiver.setResponse( - Request.ResolveAction(SINGLE_SOURCE_ID), + Request.ResolveAction(uniqueSafetySourceId), Response.SetData(safetySourceTestData.information) ) sendActionPendingIntentAndWaitWithPermission(action) TestNotificationListener.waitForSuccessNotification("Issue solved") { + assertThat(NotificationCharacteristics.safetySourceIdMatches(it, uniqueSafetySourceId)) + .isTrue() assertThat(it.hasAutoCancel()).isTrue() } } @@ -929,15 +1046,23 @@ class SafetyCenterNotificationTest { @Test fun sendActionPendingIntent_flagDisabled_pendingIntentNotSentToSource() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage( + sourceId = uniqueSafetySourceId + ) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } SafetySourceReceiver.setResponse( - Request.ResolveAction(SINGLE_SOURCE_ID), + Request.ResolveAction(uniqueSafetySourceId), Response.SetData(safetySourceTestData.information) ) SafetyCenterFlags.notificationsEnabled = false @@ -950,15 +1075,23 @@ class SafetyCenterNotificationTest { @Test fun sendActionPendingIntent_sourceStateChangedSafetyEvent_successNotification() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage( + sourceId = uniqueSafetySourceId + ) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } SafetySourceReceiver.setResponse( - Request.ResolveAction(SINGLE_SOURCE_ID), + Request.ResolveAction(uniqueSafetySourceId), Response.SetData( safetySourceTestData.information, overrideSafetyEvent = @@ -968,7 +1101,10 @@ class SafetyCenterNotificationTest { sendActionPendingIntentAndWaitWithPermission(action) - TestNotificationListener.waitForSuccessNotification("Issue solved") + TestNotificationListener.waitForSuccessNotification("Issue solved") { + assertThat(NotificationCharacteristics.safetySourceIdMatches(it, uniqueSafetySourceId)) + .isTrue() + } } @Test @@ -981,6 +1117,7 @@ class SafetyCenterNotificationTest { "notification_action_id", "Solve now!", safetySourceTestData.resolvingActionPendingIntent( + sourceId = uniqueSafetySourceId, sourceIssueActionId = "notification_action_id" ) ) @@ -1002,6 +1139,7 @@ class SafetyCenterNotificationTest { "issue_action_id", "Default action", safetySourceTestData.resolvingActionPendingIntent( + sourceId = uniqueSafetySourceId, sourceIssueActionId = "issue_action_id" ) ) @@ -1017,19 +1155,28 @@ class SafetyCenterNotificationTest { ) .build() - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + safetyCenterTestHelper.setData(uniqueSafetySourceId, data) + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve now!"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } SafetySourceReceiver.setResponse( - Request.ResolveAction(SINGLE_SOURCE_ID), + Request.ResolveAction(uniqueSafetySourceId), Response.SetData(safetySourceTestData.information) ) sendActionPendingIntentAndWaitWithPermission(action) - TestNotificationListener.waitForSuccessNotification("Solved via notification action :)") + TestNotificationListener.waitForSuccessNotification("Solved via notification action :)") { + assertThat(NotificationCharacteristics.safetySourceIdMatches(it, uniqueSafetySourceId)) + .isTrue() + } } @Test @@ -1037,14 +1184,23 @@ class SafetyCenterNotificationTest { // Here we cause a notification with an action to be posted and prepare the fake receiver // to resolve that action successfully. safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, - safetySourceTestData.criticalWithResolvingGeneralIssue + uniqueSafetySourceId, + safetySourceTestData.criticalWithResolvingGeneralIssue(sourceId = uniqueSafetySourceId) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) val action = notificationWithChannel.statusBarNotification.notification.actions.firstOrNull() checkNotNull(action) { "Notification action unexpectedly null" } - SafetySourceReceiver.setResponse(Request.ResolveAction(SINGLE_SOURCE_ID), Response.Error) + SafetySourceReceiver.setResponse( + Request.ResolveAction(uniqueSafetySourceId), + Response.Error + ) val listener = safetyCenterTestHelper.addListener() sendActionPendingIntentAndWaitWithPermission(action) @@ -1056,16 +1212,27 @@ class SafetyCenterNotificationTest { assertThat(listenerData2.inFlightActions).isEmpty() assertThat(listenerData2.status.severityLevel) .isEqualTo(SafetyCenterStatus.OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING) - TestNotificationListener.waitForSingleNotification() + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Solve issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) } @Test fun sendContentPendingIntent_singleIssue_opensSafetyCenterWithIssueVisible() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, safetySourceTestData.recommendationWithDeviceIssue ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) sendContentPendingIntent(notificationWithChannel) { waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue) @@ -1082,9 +1249,15 @@ class SafetyCenterNotificationTest { ) safetyCenterTestHelper.setData( SOURCE_ID_2, - safetySourceTestData.criticalWithResolvingGeneralIssue + safetySourceTestData.criticalWithResolvingGeneralIssue(sourceId = SOURCE_ID_2) ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = SOURCE_ID_1, + ) + ) sendContentPendingIntent(notificationWithChannel) { waitSourceIssueDisplayed(safetySourceTestData.criticalResolvingGeneralIssue) @@ -1094,8 +1267,17 @@ class SafetyCenterNotificationTest { @Test fun whenGreenIssue_notificationHasAutoCancel() { - safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + safetyCenterTestHelper.setData( + uniqueSafetySourceId, + safetySourceTestData.informationWithIssue + ) + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("Review"), + safetySourceId = uniqueSafetySourceId, + ) + ) assertThat(notificationWithChannel.statusBarNotification.hasAutoCancel()).isTrue() } @@ -1103,10 +1285,16 @@ class SafetyCenterNotificationTest { @Test fun whenNotGreenIssue_notificationDoesntHaveAutoCancel() { safetyCenterTestHelper.setData( - SINGLE_SOURCE_ID, + uniqueSafetySourceId, safetySourceTestData.recommendationWithDeviceIssue ) - val notificationWithChannel = TestNotificationListener.waitForSingleNotification() + val notificationWithChannel = + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = uniqueSafetySourceId, + ) + ) assertThat(notificationWithChannel.statusBarNotification.hasAutoCancel()).isFalse() } diff --git a/tests/hostside/safetycenter/helper-app/Android.bp b/tests/hostside/safetycenter/helper-app/Android.bp index d15caceaa..04e660134 100644 --- a/tests/hostside/safetycenter/helper-app/Android.bp +++ b/tests/hostside/safetycenter/helper-app/Android.bp @@ -31,6 +31,7 @@ android_test_helper_app { static_libs: [ "androidx.test.rules", "androidx.test.ext.junit", + "safety-center-pending-intents", "safety-center-test-util-lib", ], } diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt index 784701b8a..6afcff85a 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt @@ -19,14 +19,23 @@ package android.safetycenter.hostside.device import android.content.Context import android.os.Bundle import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID +import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCE_ID +import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCE_ISSUE_ID import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.compatibility.common.util.UiAutomatorUtils2 import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterActivity +import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterQsActivity import com.android.safetycenter.testing.SafetyCenterActivityLauncher.openPageAndExit import com.android.safetycenter.testing.SafetyCenterFlags import com.android.safetycenter.testing.SafetyCenterTestConfigs +import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID import com.android.safetycenter.testing.SafetyCenterTestHelper import com.android.safetycenter.testing.SafetyCenterTestRule +import com.android.safetycenter.testing.SafetySourceTestData +import com.android.safetycenter.testing.SafetySourceTestData.Companion.INFORMATION_ISSUE_ID +import com.android.safetycenter.testing.UiTestHelper.waitAllTextDisplayed +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -47,6 +56,7 @@ class SafetyCenterInteractionLoggingHelperTests { private val context: Context = ApplicationProvider.getApplicationContext() private val safetyCenterTestHelper = SafetyCenterTestHelper(context) private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context) + private val safetySourceTestData = SafetySourceTestData(context) @get:Rule val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper) @@ -55,12 +65,48 @@ class SafetyCenterInteractionLoggingHelperTests { SafetyCenterFlags.showSubpages = true } + @After + fun tearDown() { + // When an assertion fails, it will end up leaving the previous view open, which screws + // with the logging assertions made by this test (polluting with view events from whatever + // view was left open). Here we preemptively clear whatever's open to get back to home + UiAutomatorUtils2.getUiDevice().pressHome() + } + @Test fun openSafetyCenter() { context.launchSafetyCenterActivity {} } @Test + fun openSafetyCenterFullFromQs() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig) + safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue) + + context.launchSafetyCenterQsActivity { + openPageAndExit("Settings") { waitAllTextDisplayed(safetySourceTestData.informationIssue.title) } + } + } + + @Test + fun openSafetyCenterWithIssueIntent() { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig) + + safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue) + + val extras = Bundle() + extras.putString(EXTRA_SAFETY_SOURCE_ID, SINGLE_SOURCE_ID) + extras.putString(EXTRA_SAFETY_SOURCE_ISSUE_ID, INFORMATION_ISSUE_ID) + + context.launchSafetyCenterActivity(extras) {} + } + + @Test + fun openSafetyCenterQs() { + context.launchSafetyCenterQsActivity {} + } + + @Test fun openSubpageFromIntentExtra() { val config = safetyCenterTestConfigs.singleSourceConfig safetyCenterTestHelper.setConfig(config) diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt index 458516379..60e6e41ec 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt @@ -21,12 +21,17 @@ import android.safetycenter.SafetySourceData import android.safetycenter.SafetySourceIssue import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.safetycenter.pendingintents.PendingIntentSender +import com.android.safetycenter.testing.NotificationCharacteristics +import com.android.safetycenter.testing.SafetyCenterActivityLauncher import com.android.safetycenter.testing.SafetyCenterFlags import com.android.safetycenter.testing.SafetyCenterTestConfigs import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID import com.android.safetycenter.testing.SafetyCenterTestHelper import com.android.safetycenter.testing.SafetyCenterTestRule import com.android.safetycenter.testing.SafetySourceTestData +import com.android.safetycenter.testing.StatusBarNotificationWithChannel +import com.android.safetycenter.testing.TestNotificationListener import org.junit.Before import org.junit.Rule import org.junit.Test @@ -49,7 +54,9 @@ class SafetyCenterNotificationLoggingHelperTests { private val safetySourceTestData = SafetySourceTestData(context) private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context) - @get:Rule val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper) + @get:Rule + val safetyCenterTestRule = + SafetyCenterTestRule(safetyCenterTestHelper, withNotifications = true) @Before fun setUp() { @@ -64,6 +71,20 @@ class SafetyCenterNotificationLoggingHelperTests { safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, newTestDataWithNotifiableIssue()) } + @Test + fun openSafetyCenterFromNotification() { + safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, newTestDataWithNotifiableIssue()) + + sendContentPendingIntent( + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = SINGLE_SOURCE_ID, + ) + ) + ) + } + private fun newTestDataWithNotifiableIssue(): SafetySourceData = safetySourceTestData .defaultCriticalDataBuilder() @@ -74,4 +95,17 @@ class SafetyCenterNotificationLoggingHelperTests { .build() ) .build() + + companion object { + private fun sendContentPendingIntent( + statusBarNotificationWithChannel: StatusBarNotificationWithChannel + ) { + val contentIntent = + statusBarNotificationWithChannel.statusBarNotification.notification.contentIntent + SafetyCenterActivityLauncher.executeBlockAndExit( + launchActivity = { PendingIntentSender.send(contentIntent) }, + block = {} // No action required + ) + } + } } diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt index 5fe9e0a2a..42a2a8a89 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt @@ -24,13 +24,17 @@ import com.android.compatibility.common.util.ApiLevelUtil import com.android.os.AtomsProto.Atom import com.android.os.AtomsProto.SafetyCenterInteractionReported import com.android.os.AtomsProto.SafetyCenterInteractionReported.Action +import com.android.os.AtomsProto.SafetyCenterInteractionReported.NavigationSource import com.android.os.AtomsProto.SafetyCenterInteractionReported.ViewType import com.android.tradefed.testtype.DeviceJUnit4ClassRunner import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test import com.google.common.truth.Truth.assertThat +import java.math.BigInteger +import java.security.MessageDigest import org.junit.After import org.junit.Assume.assumeTrue import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -67,15 +71,77 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) - assertThat(safetyCenterViewedAtoms).isNotEmpty() + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.SOURCE_UNKNOWN) + assertThat(viewType).isEqualTo(ViewType.FULL) + } } @Test - fun sendNotification_recordsNotificationPostedEvent() { + fun openSafetyCenterQs_recordsSafetyCenterViewedEvent() { + helperAppRule.runTest(TEST_CLASS_NAME, "openSafetyCenterQs") + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.QUICK_SETTINGS_TILE) + assertThat(viewType).isEqualTo(ViewType.QUICK_SETTINGS) + } + } + + @Ignore // TODO: b/323269529 - Deflake this test + @Test + fun openSafetyCenterFullFromQs_recordsViewEventWithCorrectSource() { + helperAppRule.runTest(TEST_CLASS_NAME, "openSafetyCenterFullFromQs") + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + val viewTypesToNavSources = + safetyCenterViewedAtoms.associate { Pair(it.viewType, it.navigationSource) } + assertThat(viewTypesToNavSources) + .containsEntry(ViewType.FULL, NavigationSource.QUICK_SETTINGS_TILE) + } + + @Test + fun openSafetyCenterWithIssueIntent_recordsViewEventWithAssociatedIssueMetadata() { + helperAppRule.runTest(TEST_CLASS_NAME, testMethodName = "openSafetyCenterWithIssueIntent") + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.NOTIFICATION) + assertThat(encodedSafetySourceId).isEqualTo(ENCODED_SINGLE_SOURCE_ID) + assertThat(encodedIssueTypeId).isEqualTo(ENCODED_ISSUE_TYPE_ID) + } + } + + @Test + fun openSafetyCenterWithNotification_recordsViewEventWithAssociatedIssueMetadata() { assumeAtLeastUpsideDownCake("Safety Center notification APIs require Android U+") helperAppRule.runTest( testClassName = ".SafetyCenterNotificationLoggingHelperTests", + testMethodName = "openSafetyCenterFromNotification" + ) + + val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + + assertThat(safetyCenterViewedAtoms).hasSize(1) + with(safetyCenterViewedAtoms.first()) { + assertThat(navigationSource).isEqualTo(NavigationSource.NOTIFICATION) + assertThat(encodedSafetySourceId).isEqualTo(ENCODED_SINGLE_SOURCE_ID) + assertThat(encodedIssueTypeId).isEqualTo(ENCODED_ISSUE_TYPE_ID) + } + } + + @Test + fun sendNotification_recordsNotificationPostedEvent() { + assumeAtLeastUpsideDownCake("Safety Center notification APIs require Android U+") + helperAppRule.runTest( + testClassName = ".SafetyCenterNotificationLoggingHelperTests", testMethodName = "sendNotification" ) @@ -97,8 +163,7 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { assertThat(safetyCenterViewedAtoms).hasSize(1) with(safetyCenterViewedAtoms.first()) { assertThat(viewType).isEqualTo(ViewType.SUBPAGE) - assertThat(navigationSource) - .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SOURCE_UNKNOWN) + assertThat(navigationSource).isEqualTo(NavigationSource.SOURCE_UNKNOWN) assertThat(sessionId).isNotNull() } } @@ -113,8 +178,7 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { val subpageViewedEvent = safetyCenterViewedAtoms.find { it.viewType == ViewType.SUBPAGE } assertThat(subpageViewedEvent).isNotNull() - assertThat(subpageViewedEvent!!.navigationSource) - .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SAFETY_CENTER) + assertThat(subpageViewedEvent!!.navigationSource).isEqualTo(NavigationSource.SAFETY_CENTER) assertThat(safetyCenterViewedAtoms.map { it.sessionId }.distinct()).hasSize(1) } @@ -129,8 +193,7 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { assertThat(safetyCenterViewedAtoms).hasSize(1) with(safetyCenterViewedAtoms.first()) { assertThat(viewType).isEqualTo(ViewType.SUBPAGE) - assertThat(navigationSource) - .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SETTINGS) + assertThat(navigationSource).isEqualTo(NavigationSource.SETTINGS) assertThat(sessionId).isNotNull() } } @@ -148,5 +211,27 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { private companion object { const val TEST_CLASS_NAME = ".SafetyCenterInteractionLoggingHelperTests" + + // LINT.IfChange(single_source_id) + val ENCODED_SINGLE_SOURCE_ID = encodeId("test_single_source_id") + // LINT.ThenChange(/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt:issue_type_id) + + // LINT.IfChange(issue_type_id) + val ENCODED_ISSUE_TYPE_ID = encodeId("issue_type_id") + // LINT.ThenChange(/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt:issue_type_id) + + /** + * Encodes a string into an long ID. The ID is a SHA-256 of the string, truncated to 64 + * bits. + */ + fun encodeId(id: String?): Long { + if (id == null) return 0 + + val digest = MessageDigest.getInstance("MD5") + digest.update(id.toByteArray()) + + // Truncate to the size of a long + return BigInteger(digest.digest()).toLong() + } } } diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt index edf76e888..fe75a05a2 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt @@ -24,14 +24,23 @@ import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement +/** toBooleanString() doesn't seem available on all Kotlin versions we need to support. */ +private fun String.toBooleanStrictInt(): Boolean = + when (this) { + "true" -> true + "false" -> false + else -> + throw IllegalArgumentException("The string doesn't represent a boolean value: $this") + } + /** JUnit rule for host side tests that requires Safety Center to be supported and enabled. */ class RequireSafetyCenterRule(private val hostTestClass: BaseHostJUnit4Test) : TestRule { private val safetyCenterSupported: Boolean by lazy { - shellCommandStdoutOrThrow("cmd safety_center supported").toBooleanStrict() + shellCommandStdoutOrThrow("cmd safety_center supported").toBooleanStrictInt() } private val safetyCenterEnabled: Boolean by lazy { - shellCommandStdoutOrThrow("cmd safety_center enabled").toBooleanStrict() + shellCommandStdoutOrThrow("cmd safety_center enabled").toBooleanStrictInt() } override fun apply(base: Statement, description: Description): Statement { diff --git a/tests/utils/safetycenter/Android.bp b/tests/utils/safetycenter/Android.bp index 6accefae9..8514b0662 100644 --- a/tests/utils/safetycenter/Android.bp +++ b/tests/utils/safetycenter/Android.bp @@ -36,6 +36,7 @@ android_library { "kotlinx-coroutines-android", "safety-center-internal-data", "safety-center-resources-lib", + "permissions-aconfig-flags-lib", ], apex_available: [ "com.android.permission", diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/NotificationCharacteristics.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/NotificationCharacteristics.kt index 177c2359c..81b752bca 100644 --- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/NotificationCharacteristics.kt +++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/NotificationCharacteristics.kt @@ -17,18 +17,25 @@ package com.android.safetycenter.testing import android.app.Notification +import android.service.notification.StatusBarNotification +import com.android.safetycenter.internaldata.SafetyCenterIds /** The characteristic properties of a notification. */ data class NotificationCharacteristics( - val title: String, - val text: String, + val title: String? = null, + val text: String? = null, val actions: List<CharSequence> = emptyList(), val importance: Int = IMPORTANCE_ANY, - val blockable: Boolean? = null + val blockable: Boolean? = null, + val safetySourceId: String? = null, ) { companion object { const val IMPORTANCE_ANY = -1 + private fun stringMatches(actual: String?, expected: String?): Boolean { + return expected == null || actual == expected + } + private fun importanceMatches( statusBarNotificationWithChannel: StatusBarNotificationWithChannel, characteristicImportance: Int @@ -45,17 +52,31 @@ data class NotificationCharacteristics( statusBarNotificationWithChannel.channel.isBlockable == characteristicBlockable } + fun safetySourceIdMatches( + statusBarNotification: StatusBarNotification, + safetySourceId: String? + ): Boolean { + return safetySourceId == null || + SafetyCenterIds.issueKeyFromString(statusBarNotification.tag).safetySourceId == + safetySourceId + } + private fun isMatch( statusBarNotificationWithChannel: StatusBarNotificationWithChannel, characteristic: NotificationCharacteristics ): Boolean { val notif = statusBarNotificationWithChannel.statusBarNotification.notification + val extras = notif.extras return notif != null && - notif.extras.getString(Notification.EXTRA_TITLE) == characteristic.title && - notif.extras.getString(Notification.EXTRA_TEXT).orEmpty() == characteristic.text && + stringMatches(extras.getString(Notification.EXTRA_TITLE), characteristic.title) && + stringMatches(extras.getString(Notification.EXTRA_TEXT), characteristic.text) && notif.actions.orEmpty().map { it.title } == characteristic.actions && importanceMatches(statusBarNotificationWithChannel, characteristic.importance) && - blockableMatches(statusBarNotificationWithChannel, characteristic.blockable) + blockableMatches(statusBarNotificationWithChannel, characteristic.blockable) && + safetySourceIdMatches( + statusBarNotificationWithChannel.statusBarNotification, + characteristic.safetySourceId + ) } fun areMatching( diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt index 60c3b4d6a..0e31b2934 100644 --- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt +++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestConfigs.kt @@ -31,6 +31,7 @@ import android.safetycenter.config.SafetySource.SAFETY_SOURCE_TYPE_STATIC import android.safetycenter.config.SafetySourcesGroup import androidx.annotation.RequiresApi import com.android.modules.utils.build.SdkLevel +import com.android.permission.flags.Flags import com.android.safetycenter.testing.SettingsPackage.getSettingsPackageName import java.security.MessageDigest @@ -159,6 +160,14 @@ class SafetyCenterTestConfigs(private val context: Context) { /** A [SafetyCenterConfig] with a dynamic source in a different, missing package. */ val singleSourceOtherPackageConfig = singleSourceConfig(dynamicOtherPackageSafetySource) + /** A [SafetyCenterConfig] with a dynamic hidden-by-default source. */ + val hiddenSourceConfig = + singleSourceConfig( + dynamicSafetySourceBuilder(DYNAMIC_HIDDEN_ID) + .setInitialDisplayState(SafetySource.INITIAL_DISPLAY_STATE_HIDDEN) + .build() + ) + /** A simple [SafetyCenterConfig] with a source supporting all profiles. */ val singleSourceAllProfileConfig = singleSourceConfig( @@ -678,6 +687,11 @@ class SafetyCenterTestConfigs(private val context: Context) { .setSummaryResId(Resources.ID_NULL) .setIntentAction(null) .setInitialDisplayState(SafetySource.INITIAL_DISPLAY_STATE_HIDDEN) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(Resources.ID_NULL) + } + } .build() ) .build() @@ -780,6 +794,11 @@ class SafetyCenterTestConfigs(private val context: Context) { dynamicSafetySourceBuilder(id) .setProfile(SafetySource.PROFILE_ALL) .setTitleForWorkResId(android.R.string.paste) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(android.R.string.unknownName) + } + } private fun staticSafetySource(id: String) = staticSafetySourceBuilder(id).build() @@ -795,6 +814,11 @@ class SafetyCenterTestConfigs(private val context: Context) { staticSafetySourceBuilder(id) .setProfile(SafetySource.PROFILE_ALL) .setTitleForWorkResId(android.R.string.paste) + .apply { + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + setTitleForPrivateProfileResId(android.R.string.unknownName) + } + } @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) private fun issueOnlySafetySourceWithDuplicationInfo(id: String, deduplicationGroup: String) = @@ -848,7 +872,9 @@ class SafetyCenterTestConfigs(private val context: Context) { * ID of the only source provided in [singleSourceConfig], [severityZeroConfig] and * [noPageOpenConfig]. */ + // LINT.IfChange(single_source_id) const val SINGLE_SOURCE_ID = "test_single_source_id" + // LINT.ThenChange(/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt:single_source_id) /** ID of the only source provided in [singleSourceAllProfileConfig]. */ const val SINGLE_SOURCE_ALL_PROFILE_ID = "test_single_source_all_profile_id" diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt index 2c4f856bb..7e77c0827 100644 --- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt +++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetySourceTestData.kt @@ -175,6 +175,24 @@ class SafetySourceTestData(private val context: Context) { .addIssue(informationIssue) .build() + /** + * A [SafetySourceData] with a [SEVERITY_LEVEL_INFORMATION] redirecting [SafetySourceIssue] and + * a [SEVERITY_LEVEL_UNSPECIFIED] [SafetySourceStatus], to be used for a private profile entry. + */ + val unspecifiedWithIssueForPrivate = + SafetySourceData.Builder() + .setStatus( + SafetySourceStatus.Builder( + "Unspecified title for Private", + "Unspecified summary", + SEVERITY_LEVEL_UNSPECIFIED + ) + .setPendingIntent(createTestActivityRedirectPendingIntent()) + .build() + ) + .addIssue(informationIssue) + .build() + /** A [SafetySourceData] with a [SEVERITY_LEVEL_INFORMATION] [SafetySourceStatus]. */ val information = SafetySourceData.Builder() @@ -284,6 +302,24 @@ class SafetySourceTestData(private val context: Context) { /** * A [SafetySourceData] with a [SEVERITY_LEVEL_INFORMATION] redirecting [SafetySourceIssue] and + * [SafetySourceStatus], to be used for a private profile entry. + */ + val informationWithIssueForPrivate = + SafetySourceData.Builder() + .setStatus( + SafetySourceStatus.Builder( + "Ok title for Private", + "Ok summary", + SEVERITY_LEVEL_INFORMATION + ) + .setPendingIntent(createTestActivityRedirectPendingIntent()) + .build() + ) + .addIssue(informationIssue) + .build() + + /** + * A [SafetySourceData] with a [SEVERITY_LEVEL_INFORMATION] redirecting [SafetySourceIssue] and * [SafetySourceStatus]. */ val informationWithSubtitleIssue = @@ -428,6 +464,10 @@ class SafetySourceTestData(private val context: Context) { /** A [PendingIntent] used by the resolving [Action] in [criticalResolvingGeneralIssue]. */ val criticalIssueActionPendingIntent = resolvingActionPendingIntent() + /** A [PendingIntent] used by the resolving [Action] in [criticalResolvingGeneralIssue]. */ + fun criticalIssueActionPendingIntent(sourceId: String) = + resolvingActionPendingIntent(sourceId = sourceId) + /** * Returns a [PendingIntent] for a resolving [Action] with the given [sourceId], [sourceIssueId] * and [sourceIssueActionId]. Default values are the same as those used by @@ -453,6 +493,16 @@ class SafetySourceTestData(private val context: Context) { .setWillResolve(true) .build() + /** A resolving Critical [Action] */ + private fun criticalResolvingAction(sourceId: String) = + Action.Builder( + CRITICAL_ISSUE_ACTION_ID, + "Solve issue", + criticalIssueActionPendingIntent(sourceId = sourceId) + ) + .setWillResolve(true) + .build() + /** A resolving Critical [Action] with confirmation */ val criticalResolvingActionWithConfirmation: SafetySourceIssue.Action @RequiresApi(UPSIDE_DOWN_CAKE) @@ -482,6 +532,17 @@ class SafetySourceTestData(private val context: Context) { .setSuccessMessage("Issue solved") .build() + /** A resolving Critical [Action] that declares a success message */ + private fun criticalResolvingActionWithSuccessMessage(sourceId: String) = + Action.Builder( + CRITICAL_ISSUE_ACTION_ID, + "Solve issue", + criticalIssueActionPendingIntent(sourceId = sourceId) + ) + .setWillResolve(true) + .setSuccessMessage("Issue solved") + .build() + /** A [SafetySourceIssue] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and a resolving [Action]. */ val criticalResolvingIssueWithSuccessMessage = SafetySourceIssue.Builder( @@ -494,6 +555,18 @@ class SafetySourceTestData(private val context: Context) { .addAction(criticalResolvingActionWithSuccessMessage) .build() + /** A [SafetySourceIssue] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and a resolving [Action]. */ + private fun criticalResolvingIssueWithSuccessMessage(sourceId: String) = + SafetySourceIssue.Builder( + CRITICAL_ISSUE_ID, + "Critical issue title", + "Critical issue summary", + SEVERITY_LEVEL_CRITICAL_WARNING, + ISSUE_TYPE_ID + ) + .addAction(criticalResolvingActionWithSuccessMessage(sourceId = sourceId)) + .build() + /** * Another [SafetySourceIssue] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and a redirecting * [Action]. @@ -538,7 +611,10 @@ class SafetySourceTestData(private val context: Context) { * [SafetySourceIssue.Builder] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and a resolving [Action] * . */ - fun defaultCriticalResolvingIssueBuilder(issueId: String = CRITICAL_ISSUE_ID) = + fun defaultCriticalResolvingIssueBuilder( + issueId: String = CRITICAL_ISSUE_ID, + sourceId: String = SINGLE_SOURCE_ID, + ) = SafetySourceIssue.Builder( issueId, "Critical issue title", @@ -546,7 +622,7 @@ class SafetySourceTestData(private val context: Context) { SEVERITY_LEVEL_CRITICAL_WARNING, ISSUE_TYPE_ID ) - .addAction(criticalResolvingAction) + .addAction(criticalResolvingAction(sourceId)) /** * General [SafetySourceIssue] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and a resolving [Action] @@ -555,6 +631,13 @@ class SafetySourceTestData(private val context: Context) { val criticalResolvingGeneralIssue = defaultCriticalResolvingIssueBuilder().build() /** + * General [SafetySourceIssue] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and a resolving [Action] + * . + */ + private fun criticalResolvingGeneralIssue(sourceId: String) = + defaultCriticalResolvingIssueBuilder(sourceId = sourceId).build() + + /** * General [SafetySourceIssue] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and with deduplication * info and a resolving [Action]. */ @@ -580,6 +663,15 @@ class SafetySourceTestData(private val context: Context) { .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE) .build() + /** + * Device related [SafetySourceIssue] with a [SEVERITY_LEVEL_CRITICAL_WARNING] and a resolving + * [Action]. + */ + private fun criticalResolvingDeviceIssue(sourceId: String) = + defaultCriticalResolvingIssueBuilder(sourceId = sourceId) + .setIssueCategory(SafetySourceIssue.ISSUE_CATEGORY_DEVICE) + .build() + /** A [SafetySourceData.Builder] with a [SEVERITY_LEVEL_CRITICAL_WARNING] status. */ fun defaultCriticalDataBuilder() = SafetySourceData.Builder() @@ -653,6 +745,15 @@ class SafetySourceTestData(private val context: Context) { /** * A [SafetySourceData] with a [SEVERITY_LEVEL_CRITICAL_WARNING] resolving general + * [SafetySourceIssue] and [SafetySourceStatus]. + */ + fun criticalWithResolvingGeneralIssue(sourceId: String) = + defaultCriticalDataBuilder() + .addIssue(criticalResolvingGeneralIssue(sourceId = sourceId)) + .build() + + /** + * A [SafetySourceData] with a [SEVERITY_LEVEL_CRITICAL_WARNING] resolving general * [SafetySourceIssue] and [SafetySourceStatus], with confirmation dialog. */ val criticalWithResolvingGeneralIssueWithConfirmation: SafetySourceData @@ -683,6 +784,15 @@ class SafetySourceTestData(private val context: Context) { /** * A [SafetySourceData] with a [SEVERITY_LEVEL_CRITICAL_WARNING] resolving device related + * [SafetySourceIssue] and [SafetySourceStatus]. + */ + fun criticalWithResolvingDeviceIssue(sourceId: String) = + defaultCriticalDataBuilder() + .addIssue(criticalResolvingDeviceIssue(sourceId = sourceId)) + .build() + + /** + * A [SafetySourceData] with a [SEVERITY_LEVEL_CRITICAL_WARNING] resolving device related * [SafetySourceIssue] and [SafetySourceStatus] and a recommendation issue. */ val criticalWithResolvingDeviceIssueAndRecommendationIssue = @@ -710,6 +820,24 @@ class SafetySourceTestData(private val context: Context) { .build() /** + * A [SafetySourceData] with a [SEVERITY_LEVEL_CRITICAL_WARNING] resolving [SafetySourceIssue] + * and [SafetySourceStatus]. + */ + fun criticalWithResolvingIssueWithSuccessMessage(sourceId: String) = + SafetySourceData.Builder() + .setStatus( + SafetySourceStatus.Builder( + "Critical title", + "Critical summary", + SEVERITY_LEVEL_CRITICAL_WARNING + ) + .setPendingIntent(createTestActivityRedirectPendingIntent()) + .build() + ) + .addIssue(criticalResolvingIssueWithSuccessMessage(sourceId = sourceId)) + .build() + + /** * A [SafetySourceData] with a [SEVERITY_LEVEL_INFORMATION] redirecting [SafetySourceIssue] and * [SEVERITY_LEVEL_CRITICAL_WARNING] [SafetySourceStatus]. */ @@ -802,7 +930,9 @@ class SafetySourceTestData(private val context: Context) { const val CRITICAL_ISSUE_ACTION_ID = "critical_issue_action_id" /** Issue type ID for all the issues in this file */ + // LINT.IfChange(issue_type_id) const val ISSUE_TYPE_ID = "issue_type_id" + // LINT.ThenChange(/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt:issue_type_id) const val CONFIRMATION_TITLE = "Confirmation title" const val CONFIRMATION_TEXT = "Confirmation text" diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/TestNotificationListener.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/TestNotificationListener.kt index 2b2342d7a..21bf76fad 100644 --- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/TestNotificationListener.kt +++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/TestNotificationListener.kt @@ -16,6 +16,7 @@ package com.android.safetycenter.testing +import android.app.Notification import android.app.NotificationChannel import android.content.ComponentName import android.content.Context @@ -101,35 +102,8 @@ class TestNotificationListener : NotificationListenerService() { * if it is met and then violated. */ fun waitForZeroNotifications(timeout: Duration = TIMEOUT_LONG) { - waitForNotificationCount(0, timeout) - } - - /** - * Blocks until there is exactly one Safety Center notification and ensures that remains - * true for a short duration. Returns that notification, or throws an [AssertionError] if a - * this condition is not met within [timeout], or if it is met and then violated. - */ - fun waitForSingleNotification( - timeout: Duration = TIMEOUT_LONG - ): StatusBarNotificationWithChannel { - return waitForNotificationCount(1, timeout).first() - } - - /** - * Blocks until there are exactly [count] Safety Center notifications and ensures that - * remains true for a short duration. Returns those notifications, or throws an - * [AssertionError] if a this condition is not met within [timeout], or if it is met and - * then violated. - */ - private fun waitForNotificationCount( - count: Int, - timeout: Duration = TIMEOUT_LONG - ): List<StatusBarNotificationWithChannel> { - return waitForNotificationsToSatisfy( - timeout = timeout, - description = "$count notifications" - ) { - it.size == count + waitForNotificationsToSatisfy(timeout = timeout, description = "No notifications") { + it.isEmpty() } } @@ -175,15 +149,19 @@ class TestNotificationListener : NotificationListenerService() { successMessage: String, onNotification: (StatusBarNotification) -> Unit = {} ) { - val successNotificationWithChannel = - waitForSingleNotificationMatching( - NotificationCharacteristics( - successMessage, - "", - actions = emptyList(), - ) - ) - val statusBarNotification = successNotificationWithChannel.statusBarNotification + // Only wait for the notification event and don't wait for all notifications to "settle" + // as this notification is auto-cancelled after 10s; which can cause flakyness. + val statusBarNotification = + (runBlockingWithTimeout { + waitForNotificationEventAsync { + (it is NotificationPosted && + it.statusBarNotification.notification + ?.extras + ?.getString(Notification.EXTRA_TITLE) == successMessage) + } + } + as NotificationPosted) + .statusBarNotification onNotification(statusBarNotification) // Cancel the notification directly to speed up the tests as it's only auto-cancelled // after 10 seconds, and the teardown waits for all notifications to be cancelled to @@ -253,6 +231,17 @@ class TestNotificationListener : NotificationListenerService() { return currentNotifications } + private suspend fun waitForNotificationEventAsync( + predicate: (NotificationEvent) -> Boolean + ): NotificationEvent { + var event: NotificationEvent + do { + event = safetyCenterNotificationEvents.receive() + Log.d(TAG, "Received notification event: $event") + } while (!predicate(event)) + return event + } + private fun getSafetyCenterNotifications(): List<StatusBarNotificationWithChannel> { return with(getInstanceOrThrow()) { val notificationsSnapshot = |