summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/res/layout-v33/safety_center_toggle_button.xml2
-rw-r--r--PermissionController/res/values-de/strings.xml2
-rw-r--r--PermissionController/res/values-el/strings.xml10
-rw-r--r--PermissionController/res/values-es-rUS/strings.xml2
-rw-r--r--PermissionController/res/values-es/strings.xml4
-rw-r--r--PermissionController/res/values-ldrtl/integers.xml18
-rw-r--r--PermissionController/res/values-zh-rCN/strings.xml6
-rw-r--r--PermissionController/res/values/integers.xml18
-rw-r--r--PermissionController/res/xml/roles.xml3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/appops/data/repository/v31/AppOpRepository.kt17
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/GetPermissionGroupUsageDetailsUseCase.kt3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/PermissionUsageUtils.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java18
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt41
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt1
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/LocationUtils.java3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt12
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java65
-rw-r--r--PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionGroupUsageDetailsUseCaseTest.kt12
-rw-r--r--PermissionController/tests/permissionui/Android.bp1
-rw-r--r--PermissionController/tests/permissionui/AndroidTest.xml8
-rw-r--r--PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/Android.bp34
-rw-r--r--PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/AndroidManifest.xml25
-rw-r--r--PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAllAppPermissionFragmentTest.kt57
-rw-r--r--PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAppPermissionFragmentTest.kt38
-rw-r--r--PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/TestAppUtils.kt4
-rw-r--r--PermissionController/wear-permission-components/src/wear.permission.components/material2/ToggleChip.kt5
-rw-r--r--PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButtonStyle.kt13
-rw-r--r--PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffold.kt23
-rw-r--r--PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffoldPaddingDefaults.kt8
-rw-r--r--PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionToggleControl.kt4
-rw-r--r--SafetyCenter/Resources/res/raw-v36/safety_center_config.xml20
-rw-r--r--service/java/com/android/ecm/EnhancedConfirmationService.java2
-rw-r--r--tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java3
-rw-r--r--tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt18
-rw-r--r--tests/cts/permissionpolicy/res/raw/android_manifest.xml8
-rw-r--r--tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt294
-rw-r--r--tests/cts/role/src/android/app/role/cts/RoleManagerTest.java3
40 files changed, 537 insertions, 278 deletions
diff --git a/PermissionController/res/layout-v33/safety_center_toggle_button.xml b/PermissionController/res/layout-v33/safety_center_toggle_button.xml
index f790e734e..52d62a7ed 100644
--- a/PermissionController/res/layout-v33/safety_center_toggle_button.xml
+++ b/PermissionController/res/layout-v33/safety_center_toggle_button.xml
@@ -35,8 +35,10 @@
android:text="@string/available"/>
</LinearLayout>
+ <!-- The X scale controls the direction of the arrow, based on the language direction -->
<ImageView
android:id="@+id/arrow_icon"
style="@style/SafetyCenterQsToggleArrow"
+ android:scaleX="@integer/mirror_x_scale"
android:visibility="gone"/>
</LinearLayout>
diff --git a/PermissionController/res/values-de/strings.xml b/PermissionController/res/values-de/strings.xml
index 8d52ca43d..69bcee8b4 100644
--- a/PermissionController/res/values-de/strings.xml
+++ b/PermissionController/res/values-de/strings.xml
@@ -443,7 +443,7 @@
<string name="default_app_recommended" msgid="5669584821778942909">"Für dein Gerät optimiert"</string>
<string name="default_app_others" msgid="7793029848126079876">"Sonstige"</string>
<string name="default_app_none" msgid="9084592086808194457">"Keine"</string>
- <string name="default_app_system_default" msgid="6218386768175513760">"(System-Standard­einstellung)"</string>
+ <string name="default_app_system_default" msgid="6218386768175513760">"(System-Stan­dard­einstellung)"</string>
<string name="default_app_no_apps" msgid="115720991680586885">"Keine Apps"</string>
<string name="default_payment_app_other_nfc_services" msgid="5957633798695758917">"Andere NFC‑Dienste"</string>
<string name="car_default_app_selected" msgid="5416420830430644174">"Ausgewählt"</string>
diff --git a/PermissionController/res/values-el/strings.xml b/PermissionController/res/values-el/strings.xml
index 97f62ba24..b066c75ca 100644
--- a/PermissionController/res/values-el/strings.xml
+++ b/PermissionController/res/values-el/strings.xml
@@ -455,13 +455,13 @@
<string name="home_missing_work_profile_support" msgid="1756855847669387977">"Δεν υποστηρίζει προφίλ εργασίας"</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>
- <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_channel_name" msgid="3144954065936288440">"Κοινοποίηση δεδομένων αποσφαλμάτωσης"</string>
+ <string name="incident_report_notification_title" msgid="4635984625656519773">"Κοινοποίηση λεπτομερ. δεδομ. αποσφαλμάτωσης;"</string>
+ <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="1819244417678973362">"Η εφαρμογή <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>. Οι αναφορές σφάλματος περιλαμβάνουν προσωπικά στοιχεία σχετικά με τη συσκευή σας ή στοιχεία που έχουν καταγράψει οι εφαρμογές, για παράδειγμα, ονόματα χρηστών, δεδομένα τοποθεσίας, αναγνωριστικά συσκευών και πληροφορίες δικτύου. Να κοινοποιείτε τις αναφορές σφάλματος μόνο σε άτομα και εφαρμογές στα οποία θεωρείτε ότι μπορείτε να εμπιστεύεστε αυτές τις πληροφορίες.\n\nΝα επιτραπεί στην εφαρμογή <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_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>
diff --git a/PermissionController/res/values-es-rUS/strings.xml b/PermissionController/res/values-es-rUS/strings.xml
index 0a8908fd7..94179a6e7 100644
--- a/PermissionController/res/values-es-rUS/strings.xml
+++ b/PermissionController/res/values-es-rUS/strings.xml
@@ -370,7 +370,7 @@
<string name="role_dialer_request_description" msgid="6288839625724909320">"Esta app obtendrá acceso a la cámara, los contactos, micrófono, teléfono y SMS"</string>
<string name="role_dialer_search_keywords" msgid="3324448983559188087">"marcador"</string>
<string name="role_sms_label" msgid="8456999857547686640">"App de SMS predeterminada"</string>
- <string name="role_sms_short_label" msgid="4371444488034692243">"app de SMS"</string>
+ <string name="role_sms_short_label" msgid="4371444488034692243">"App de SMS"</string>
<string name="role_sms_description" msgid="3424020199148153513">"Apps que te permiten usar tu número de teléfono para enviar y recibir mensajes de texto cortos, fotos, videos y mucho más"</string>
<string name="role_sms_request_title" msgid="7953552109601185602">"¿Quieres establecer <xliff:g id="APP_NAME">%1$s</xliff:g> como app de SMS predeterminada?"</string>
<string name="role_sms_request_description" msgid="2691004766132144886">"Se le otorgará acceso a esta app a tu cámara, contactos, archivos y contenido multimedia, micrófono, teléfono y SMS"</string>
diff --git a/PermissionController/res/values-es/strings.xml b/PermissionController/res/values-es/strings.xml
index 6c2e76289..6ec8bb7b1 100644
--- a/PermissionController/res/values-es/strings.xml
+++ b/PermissionController/res/values-es/strings.xml
@@ -252,13 +252,13 @@
<string name="app_permission_most_recent_denied_summary" msgid="7659497197737708112">"Actualmente denegado / Último acceso: <xliff:g id="TIME_DATE">%1$s</xliff:g>"</string>
<string name="app_permission_never_accessed_summary" msgid="401346181461975090">"No ha accedido nunca"</string>
<string name="app_permission_never_accessed_denied_summary" msgid="6596000497490905146">"Denegado / Último acceso: Nunca"</string>
- <string name="allowed_header" msgid="7769277978004790414">"Permitidas"</string>
+ <string name="allowed_header" msgid="7769277978004790414">"Con permiso"</string>
<string name="allowed_always_header" msgid="6455903312589013545">"Con permiso siempre"</string>
<string name="allowed_foreground_header" msgid="6845655788447833353">"Permitidas solo mientras se usan"</string>
<string name="allowed_storage_scoped" msgid="5383645873719086975">"Pueden acceder solo al contenido multimedia"</string>
<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 permitido"</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 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>
diff --git a/PermissionController/res/values-ldrtl/integers.xml b/PermissionController/res/values-ldrtl/integers.xml
new file mode 100644
index 000000000..ca998ad16
--- /dev/null
+++ b/PermissionController/res/values-ldrtl/integers.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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>
+ <integer name="mirror_x_scale">-1</integer>
+</resources>
diff --git a/PermissionController/res/values-zh-rCN/strings.xml b/PermissionController/res/values-zh-rCN/strings.xml
index 59168c3ae..6e1a2d1a3 100644
--- a/PermissionController/res/values-zh-rCN/strings.xml
+++ b/PermissionController/res/values-zh-rCN/strings.xml
@@ -196,7 +196,7 @@
<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_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>
@@ -487,8 +487,8 @@
<string name="permgrouprequest_nearby_devices" msgid="2272829282660436700">"要允许“&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;”查找、连接到附近设备以及确定附近设备的相对位置吗?"</string>
<string name="permgrouprequest_device_aware_nearby_devices" msgid="5293478278408567442">"要允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;在&lt;b&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/b&gt;上查找、连接到附近设备以及确定附近设备的相对位置吗?"</string>
<string name="permgroupupgraderequestdetail_nearby_devices" msgid="6877531270654738614">"要允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;查找、连接附近设备以及确定附近设备的相对位置吗?"<annotation id="link">"您可以在“设置”中允许。"</annotation></string>
- <string name="permgrouprequest_fineupgrade" msgid="2334242928821697672">"要将“<xliff:g id="APP_NAME">&lt;b&gt;%1$s&lt;/b&gt;</xliff:g>”可以使用的位置信息从大致位置改为确切位置吗?"</string>
- <string name="permgrouprequest_device_aware_fineupgrade" msgid="4453775952305587571">"要将<xliff:g id="APP_NAME">&lt;b&gt;%1$s&lt;/b&gt;</xliff:g>在&lt;b&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/b&gt;上的位置信息访问权限从大致位置信息改为确切位置信息吗?"</string>
+ <string name="permgrouprequest_fineupgrade" msgid="2334242928821697672">"要将“<xliff:g id="APP_NAME">&lt;b&gt;%1$s&lt;/b&gt;</xliff:g>”可以使用的位置信息从大致位置改为精确位置吗?"</string>
+ <string name="permgrouprequest_device_aware_fineupgrade" msgid="4453775952305587571">"要将<xliff:g id="APP_NAME">&lt;b&gt;%1$s&lt;/b&gt;</xliff:g>在&lt;b&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/b&gt;上的位置信息访问权限从大致位置信息改为精确位置信息吗?"</string>
<string name="permgrouprequest_coarselocation" msgid="7244605063736425232">"要允许“&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;”获取此设备的大致位置信息吗?"</string>
<string name="permgrouprequest_device_aware_coarselocation" msgid="8367540370912066757">"要允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;获取&lt;b&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/b&gt;的大致位置信息吗?"</string>
<string name="permgrouprequest_finelocation_imagetext" msgid="1313062433398914334">"确切位置"</string>
diff --git a/PermissionController/res/values/integers.xml b/PermissionController/res/values/integers.xml
new file mode 100644
index 000000000..c65ec99de
--- /dev/null
+++ b/PermissionController/res/values/integers.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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>
+ <integer name="mirror_x_scale">1</integer>
+</resources>
diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml
index 8a8a05c49..ae8adc5ab 100644
--- a/PermissionController/res/xml/roles.xml
+++ b/PermissionController/res/xml/roles.xml
@@ -1940,7 +1940,8 @@
</role>
<role
- name="android.app.role.COMPANION_DEVICE_SENSOR_DEVICE_STREAMING"
+ name="android.app.role.COMPANION_DEVICE_VIRTUAL_DEVICE"
+ allowBypassingQualification="true"
exclusive="false"
exclusivity="none"
featureFlag="android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole"
diff --git a/PermissionController/src/com/android/permissioncontroller/appops/data/repository/v31/AppOpRepository.kt b/PermissionController/src/com/android/permissioncontroller/appops/data/repository/v31/AppOpRepository.kt
index 21ced3b28..7a59aa2bc 100644
--- a/PermissionController/src/com/android/permissioncontroller/appops/data/repository/v31/AppOpRepository.kt
+++ b/PermissionController/src/com/android/permissioncontroller/appops/data/repository/v31/AppOpRepository.kt
@@ -27,7 +27,6 @@ import android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED
import android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY
import android.app.Application
import android.os.UserHandle
-import android.permission.flags.Flags
import android.util.Log
import com.android.modules.utils.build.SdkLevel
import com.android.permissioncontroller.DeviceUtils
@@ -74,7 +73,7 @@ interface AppOpRepository {
*/
fun getDiscreteOps(
opNames: List<String>,
- coroutineScope: CoroutineScope
+ coroutineScope: CoroutineScope,
): Flow<List<DiscretePackageOpsModel>>
companion object {
@@ -82,7 +81,7 @@ interface AppOpRepository {
fun getInstance(
application: Application,
- permissionRepository: PermissionRepository
+ permissionRepository: PermissionRepository,
): AppOpRepository =
instance
?: synchronized(this) {
@@ -104,7 +103,7 @@ class AppOpRepositoryImpl(
override fun getDiscreteOps(
opNames: List<String>,
- coroutineScope: CoroutineScope
+ coroutineScope: CoroutineScope,
): Flow<List<DiscretePackageOpsModel>> {
return callbackFlow {
var job: Job? = null
@@ -112,9 +111,7 @@ class AppOpRepositoryImpl(
fun sendUpdate() {
if (job == null || job?.isActive == false) {
- job = coroutineScope.launch(dispatcher) {
- trySend(getDiscreteOps(opNames))
- }
+ job = coroutineScope.launch(dispatcher) { trySend(getDiscreteOps(opNames)) }
}
}
@@ -229,10 +226,10 @@ class AppOpRepositoryImpl(
packageOps.ops.map { opEntry ->
AppOpUsageModel(
opEntry.opStr,
- opEntry.getLastAccessTime(OPS_LAST_ACCESS_FLAGS)
+ opEntry.getLastAccessTime(OPS_LAST_ACCESS_FLAGS),
)
},
- UserHandle.getUserHandleForUid(packageOps.uid).identifier
+ UserHandle.getUserHandleForUid(packageOps.uid).identifier,
)
}
}
@@ -254,7 +251,7 @@ class AppOpRepositoryImpl(
if (SdkLevel.isAtLeastT()) {
opNames.add(AppOpsManager.OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO)
}
- if (SdkLevel.isAtLeastV() && Flags.locationBypassPrivacyDashboardEnabled()) {
+ if (SdkLevel.isAtLeastV()) {
opNames.add(AppOpsManager.OPSTR_EMERGENCY_LOCATION)
}
return opNames
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/GetPermissionGroupUsageDetailsUseCase.kt b/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/GetPermissionGroupUsageDetailsUseCase.kt
index 5ba649fd3..cc49b4ef3 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/GetPermissionGroupUsageDetailsUseCase.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/GetPermissionGroupUsageDetailsUseCase.kt
@@ -227,8 +227,7 @@ class GetPermissionGroupUsageDetailsUseCase(
}
}
- private fun isLocationByPassEnabled(): Boolean =
- SdkLevel.isAtLeastV() && Flags.locationBypassPrivacyDashboardEnabled()
+ private fun isLocationByPassEnabled(): Boolean = SdkLevel.isAtLeastV()
/**
* Determine if an op should be in its own cluster and hence display as an individual entry in
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/PermissionUsageUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/PermissionUsageUtils.kt
index 7f5910ac1..9526d0bdd 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/PermissionUsageUtils.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/domain/usecase/v31/PermissionUsageUtils.kt
@@ -21,7 +21,6 @@ import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.UserHandle
-import android.permission.flags.Flags
import androidx.annotation.VisibleForTesting
import com.android.modules.utils.build.SdkLevel
import com.android.permissioncontroller.permission.data.repository.v31.PermissionRepository
@@ -99,5 +98,4 @@ private fun isTelecomPackage(packageName: String, permissionGroup: String): Bool
permissionGroup == Manifest.permission_group.MICROPHONE)
}
-fun isLocationByPassEnabled(): Boolean =
- SdkLevel.isAtLeastV() && Flags.locationBypassPrivacyDashboardEnabled()
+fun isLocationByPassEnabled(): Boolean = SdkLevel.isAtLeastV()
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java
index 026f108fa..39ca24a71 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/auto/AutoAppPermissionFragment.java
@@ -182,10 +182,8 @@ public class AutoAppPermissionFragment extends AutoSettingsFrameFragment
if (SdkLevel.isAtLeastV()) {
mSensorPrivacyManager = requireContext().getSystemService(SensorPrivacyManager.class);
mCameraPrivacyAllowlist = mSensorPrivacyManager.getCameraPrivacyAllowlist();
- if (Flags.addBannersToPrivacySensitiveAppsForAaos()) {
- mAutomotiveLocationBypassAllowlist =
- LocationUtils.getAutomotiveLocationBypassAllowlist(requireContext());
- }
+ mAutomotiveLocationBypassAllowlist =
+ LocationUtils.getAutomotiveLocationBypassAllowlist(requireContext());
}
}
@@ -317,13 +315,11 @@ public class AutoAppPermissionFragment extends AutoSettingsFrameFragment
if (Manifest.permission_group.CAMERA.equals(mPermGroupName)) {
mViewModel.getSensorStatusLiveData().observe(this, this::setSensorStatus);
}
- if (Flags.addBannersToPrivacySensitiveAppsForAaos()) {
- if (Manifest.permission_group.LOCATION.equals(mPermGroupName)) {
- mViewModel.getSensorStatusLiveData().observe(this, this::setSensorStatus);
- }
- if (Manifest.permission_group.MICROPHONE.equals(mPermGroupName)) {
- mViewModel.getSensorStatusLiveData().observe(this, this::setSensorStatus);
- }
+ if (Manifest.permission_group.LOCATION.equals(mPermGroupName)) {
+ mViewModel.getSensorStatusLiveData().observe(this, this::setSensorStatus);
+ }
+ if (Manifest.permission_group.MICROPHONE.equals(mPermGroupName)) {
+ mViewModel.getSensorStatusLiveData().observe(this, this::setSensorStatus);
}
}
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 969ac17eb..e995588b2 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionGroupsFragment.java
@@ -492,7 +492,7 @@ public final class AppPermissionGroupsFragment extends SettingsWithLargeHeader i
}
private boolean isArchivingEnabled() {
- return SdkLevel.isAtLeastV() && Flags.archivingReadOnly();
+ return SdkLevel.isAtLeastV();
}
private void setAutoRevokeToggleState(HibernationSettingState state) {
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 ad21ab220..d8eeb8fd9 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
@@ -30,7 +30,6 @@ import android.graphics.drawable.Drawable
import android.location.LocationManager
import android.os.Build
import android.os.UserHandle
-import android.permission.flags.Flags
import androidx.annotation.RequiresApi
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.AndroidViewModel
@@ -406,8 +405,7 @@ class PermissionUsageDetailsViewModel(
}
}
- private fun isLocationByPassEnabled(): Boolean =
- SdkLevel.isAtLeastV() && Flags.locationBypassPrivacyDashboardEnabled()
+ private fun isLocationByPassEnabled(): Boolean = SdkLevel.isAtLeastV()
fun create(
app: Application,
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 2933d6fda..38a3b44e9 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt
@@ -44,6 +44,7 @@ import com.android.permissioncontroller.permission.ui.wear.model.WearAppPermissi
import com.android.permissioncontroller.permission.ui.wear.model.WearLocationProviderInterceptDialogViewModel
import com.android.permissioncontroller.permission.utils.ArrayUtils
import com.android.permissioncontroller.permission.utils.LocationUtils
+import com.android.permissioncontroller.permission.utils.PermissionMapping
import com.android.permissioncontroller.permission.utils.Utils
import com.android.permissioncontroller.permission.utils.legacy.LegacySafetyNetLogger
import com.android.permissioncontroller.permission.utils.navigateSafe
@@ -59,7 +60,7 @@ class WearAppPermissionGroupsHelper(
val wearViewModel: WearAppPermissionUsagesViewModel,
val revokeDialogViewModel: AppPermissionGroupsRevokeDialogViewModel,
val locationProviderInterceptDialogViewModel: WearLocationProviderInterceptDialogViewModel,
- private val toggledGroups: ArraySet<AppPermissionGroup> = ArraySet()
+ private val toggledGroups: ArraySet<AppPermissionGroup> = ArraySet(),
) {
fun getPermissionGroupChipParams(
appPermissionUsages: List<AppPermissionUsage>
@@ -71,7 +72,7 @@ class WearAppPermissionGroupsHelper(
viewModel.extractGroupUsageLastAccessTime(
groupUsageLastAccessTime,
appPermissionUsages,
- packageName
+ packageName,
)
val groupUiInfos = viewModel.packagePermGroupsLiveData.value
val groups: List<AppPermissionGroup> = appPermissions.permissionGroups
@@ -92,7 +93,7 @@ class WearAppPermissionGroupsHelper(
groups
.filter { Utils.shouldShowPermission(context, it) }
- .partition { it.declaringPackage == Utils.OS_PKG }
+ .partition { PermissionMapping.isPlatformPermissionGroup(it.name) }
.let { it.first.plus(it.second) }
.forEach { group ->
if (Utils.areGroupPermissionsIndividuallyControlled(context, group.name)) {
@@ -107,7 +108,7 @@ class WearAppPermissionGroupsHelper(
checked = group.areRuntimePermissionsGranted(arrayOf(perm.name)),
onCheckedChanged = { checked ->
run { onPermissionGrantedStateChanged(group, perm, checked) }
- }
+ },
)
)
}
@@ -123,10 +124,10 @@ class WearAppPermissionGroupsHelper(
getSummary(
category,
it,
- groupUsageLastAccessTime[it.groupName]
+ groupUsageLastAccessTime[it.groupName],
)
},
- onClick = { onPermissionGroupClicked(group, category.categoryName) }
+ onClick = { onPermissionGroupClicked(group, category.categoryName) },
)
)
}
@@ -138,7 +139,7 @@ class WearAppPermissionGroupsHelper(
private fun getSummary(
category: Category?,
groupUiInfo: GroupUiInfo,
- lastAccessTime: Long?
+ lastAccessTime: Long?,
): String {
val grantSummary =
getGrantSummary(category, groupUiInfo)?.let { context.getString(it) } ?: ""
@@ -196,7 +197,7 @@ class WearAppPermissionGroupsHelper(
private fun onPermissionGrantedStateChanged(
group: AppPermissionGroup,
perm: PermissionInfo,
- checked: Boolean
+ checked: Boolean,
) {
if (checked) {
group.grantRuntimePermissions(true, false, arrayOf(perm.name))
@@ -247,7 +248,7 @@ class WearAppPermissionGroupsHelper(
revokeDialogViewModel.hasConfirmedRevoke = true
}
revokeDialogViewModel.dismissDialog()
- }
+ },
)
} else {
revokePermissionInGroup(group, perm.name)
@@ -261,7 +262,7 @@ class WearAppPermissionGroupsHelper(
if ("user" == Build.TYPE) {
Log.e(
TAG,
- "The impossible happens, permission $permName is not in group $group.name."
+ "The impossible happens, permission $permName is not in group $group.name.",
)
null
} else {
@@ -291,13 +292,13 @@ class WearAppPermissionGroupsHelper(
private fun showRevocationWarningDialog(
messageId: Int,
onOkButtonClick: () -> Unit,
- onCancelButtonClick: () -> Unit = { revokeDialogViewModel.dismissDialog() }
+ onCancelButtonClick: () -> Unit = { revokeDialogViewModel.dismissDialog() },
) {
revokeDialogViewModel.revokeDialogArgs =
RevokeDialogArgs(
messageId = messageId,
onOkButtonClick = onOkButtonClick,
- onCancelButtonClick = onCancelButtonClick
+ onCancelButtonClick = onCancelButtonClick,
)
revokeDialogViewModel.showDialogLiveData.value = true
}
@@ -315,13 +316,15 @@ class WearAppPermissionGroupsHelper(
LocationUtils.isLocationGroupAndControllerExtraPackage(
context,
permGroupName,
- packageName
+ packageName,
)
) {
// Redirect to location controller extra package settings.
LocationUtils.startLocationControllerExtraPackageSettings(context, user)
- } else if (permGroupName.equals(HEALTH_PERMISSION_GROUP)
- && android.permission.flags.Flags.replaceBodySensorPermissionEnabled()) {
+ } else if (
+ permGroupName.equals(HEALTH_PERMISSION_GROUP) &&
+ android.permission.flags.Flags.replaceBodySensorPermissionEnabled()
+ ) {
// Redirect to Health&Fitness UI
Utils.navigateToAppHealthConnectSettings(fragment.requireContext(), packageName, user)
} else {
@@ -333,7 +336,7 @@ class WearAppPermissionGroupsHelper(
user,
caller,
sessionId,
- grantCategory
+ grantCategory,
)
fragment.findNavController().navigateSafe(R.id.perm_groups_to_app, args)
}
@@ -364,7 +367,7 @@ class WearAppPermissionGroupsHelper(
viewModel.setAutoRevoke(checked)
Log.w(TAG, "setAutoRevoke $checked")
}
- }
+ },
)
}
@@ -382,12 +385,12 @@ data class PermissionGroupChipParam(
val enabled: Boolean = true,
val checked: Boolean? = null,
val onClick: () -> Unit = {},
- val onCheckedChanged: (Boolean) -> Unit = {}
+ val onCheckedChanged: (Boolean) -> Unit = {},
)
data class AutoRevokeChipParam(
val labelRes: Int,
val visible: Boolean,
val checked: Boolean = false,
- val onCheckedChanged: (Boolean) -> Unit
+ val onCheckedChanged: (Boolean) -> Unit,
)
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt
index 3ed58cf4a..f918da729 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt
@@ -62,6 +62,7 @@ fun WearGrantPermissionsScreen(
val materialUIVersion = ResourceHelper.materialUIVersionInApp
ScrollableScreen(
materialUIVersion = materialUIVersion,
+ asScalingList = true,
showTimeText = false,
image = icon.value,
title = groupMessage.value,
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/LocationUtils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/LocationUtils.java
index 3d1e44b6a..76ce9b273 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/LocationUtils.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/LocationUtils.java
@@ -40,7 +40,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import com.android.modules.utils.build.SdkLevel;
-import com.android.permission.flags.Flags;
import com.android.permissioncontroller.PermissionControllerApplication;
import com.android.permissioncontroller.R;
@@ -117,7 +116,7 @@ public class LocationUtils {
/** Checks if the provided package is an automotive location bypass allowlisted package. */
public static boolean isAutomotiveLocationBypassAllowlistedPackage(
Context context, String packageName) {
- return SdkLevel.isAtLeastV() && Flags.addBannersToPrivacySensitiveAppsForAaos()
+ return SdkLevel.isAtLeastV()
&& getAutomotiveLocationBypassAllowlist(context).contains(packageName);
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
index 93a1a66df..1693b32d1 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt
@@ -45,7 +45,7 @@ object PermissionMapping {
listOf(
Manifest.permission_group.LOCATION,
Manifest.permission_group.CAMERA,
- Manifest.permission_group.MICROPHONE
+ Manifest.permission_group.MICROPHONE,
)
@JvmField
@@ -55,7 +55,7 @@ object PermissionMapping {
listOf(
Manifest.permission_group.STORAGE,
Manifest.permission_group.READ_MEDIA_AURAL,
- Manifest.permission_group.READ_MEDIA_VISUAL
+ Manifest.permission_group.READ_MEDIA_VISUAL,
)
val PARTIAL_MEDIA_PERMISSIONS: MutableSet<String> = mutableSetOf()
@@ -370,7 +370,7 @@ object PermissionMapping {
val appSupportsPickerPrompt =
group.permissions[Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED]?.isImplicit ==
- false
+ false
return if (appSupportsPickerPrompt) {
PARTIAL_MEDIA_PERMISSIONS
@@ -402,11 +402,7 @@ object PermissionMapping {
if (opName == AppOpsManager.OPSTR_PHONE_CALL_CAMERA) {
return Manifest.permission_group.CAMERA
}
- if (
- SdkLevel.isAtLeastV() &&
- Flags.locationBypassPrivacyDashboardEnabled() &&
- opName == AppOpsManager.OPSTR_EMERGENCY_LOCATION
- ) {
+ if (SdkLevel.isAtLeastV() && opName == AppOpsManager.OPSTR_EMERGENCY_LOCATION) {
return Manifest.permission_group.LOCATION
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java
index 327142896..425375d7a 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java
@@ -39,6 +39,7 @@ import static android.content.Intent.EXTRA_REASON;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED;
@@ -82,6 +83,7 @@ import android.health.connect.HealthConnectManager;
import android.health.connect.HealthPermissions;
import android.os.Binder;
import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.os.Parcelable;
import android.os.UserHandle;
import android.os.UserManager;
@@ -1109,10 +1111,23 @@ public final class Utils {
return false;
}
- // Always show Fitness&Wellness chip on Wear.
+ // Only show Fitness&Wellness chip on Wear if the app is requesting system permissions.
if (Flags.replaceBodySensorPermissionEnabled()
- && pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
- return true;
+ && pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ Set<String> requestedPermissions = new HashSet<>(packageInfo.getRequestedPermissions());
+ for (PermissionInfo permission : permissions) {
+ if (!requestedPermissions.contains(permission.name)) {
+ continue;
+ }
+ String appOpStr = AppOpsManager.permissionToOp(permission.name);
+ if (appOpStr != null
+ && !appOpStr.equals(AppOpsManager.OPSTR_READ_WRITE_HEALTH_DATA)) {
+ // Found system health permission. Show the chip.
+ return true;
+ }
+ }
+ // No valid system permissions are requested.
+ return false;
}
// Check in permission is already granted as we should not hide it in the UX at that point.
@@ -1171,45 +1186,29 @@ public final class Utils {
}
}
- // Split permission only applies to READ_HEART_RATE.
- if (!requestedHealthPermissions.contains(HealthPermissions.READ_HEART_RATE)) {
- return false;
- }
-
- // If there are other health permissions (other than READ_HEALTH_DATA_IN_BACKGROUND)
- // don't consider this a pure split-permission request.
- if (requestedHealthPermissions.size() > 2) {
+ if (!isValidSplitHealthPermissions(requestedHealthPermissions)) {
return false;
}
- boolean isBackgroundPermissionRequested =
- requestedHealthPermissions.contains(
- HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND);
- // If there are two health permissions declared, make sure the other is
- // READ_HEALTH_DATA_IN_BACKGROUND.
- if (requestedHealthPermissions.size() == 2 && !isBackgroundPermissionRequested) {
- return false;
- }
-
- // If READ_HEALTH_DATA_IN_BACKGROUND is requested, check permission flag to see if is from
- // split permission.
- if (isBackgroundPermissionRequested) {
- int readHealthDataInBackgroundFlag =
- pm.getPermissionFlags(
- HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND, packageName, user);
- if (!isFromSplitPermission(readHealthDataInBackgroundFlag)) {
+ int targetSdk = packageInfo.getTargetSdkVersion();
+ for (String perm : requestedHealthPermissions) {
+ if (!isFromSplitPermission(pm.getPermissionFlags(perm, packageName, user), targetSdk)) {
return false;
}
}
+ return true;
+ }
- // Check READ_HEART_RATE permission flag to see if is from split permission.
- int readHeartRateFlag =
- pm.getPermissionFlags(HealthPermissions.READ_HEART_RATE, packageName, user);
- return isFromSplitPermission(readHeartRateFlag);
+ private static boolean isValidSplitHealthPermissions(List<String> permissions) {
+ return (permissions.size() == 1 && permissions.contains(HealthPermissions.READ_HEART_RATE))
+ || (permissions.size() == 2 && permissions.contains(HealthPermissions.READ_HEART_RATE)
+ && permissions.contains(HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND));
}
- private static boolean isFromSplitPermission(int permissionFlag) {
- return (permissionFlag & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0;
+ private static boolean isFromSplitPermission(int permissionFlag, int targetSdk) {
+ return (targetSdk >= Build.VERSION_CODES.M)
+ ? (permissionFlag & PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0
+ : (permissionFlag & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0;
}
/**
diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionGroupUsageDetailsUseCaseTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionGroupUsageDetailsUseCaseTest.kt
index cb36de2b1..b73113ffc 100644
--- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionGroupUsageDetailsUseCaseTest.kt
+++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/domain/usecase/GetPermissionGroupUsageDetailsUseCaseTest.kt
@@ -21,10 +21,12 @@ import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
+import android.os.Build
import android.os.UserHandle
import android.permission.flags.Flags
import android.platform.test.annotations.RequiresFlagsEnabled
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.modules.utils.build.SdkLevel
import com.android.permissioncontroller.PermissionControllerApplication
@@ -846,7 +848,10 @@ class GetPermissionGroupUsageDetailsUseCaseTest {
@Test
@Ignore("b/365004787")
- @RequiresFlagsEnabled(Flags.FLAG_LOCATION_BYPASS_PRIVACY_DASHBOARD_ENABLED)
+ @SdkSuppress(
+ minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ codeName = "VanillaIceCream",
+ )
fun emergencyAccessesAreNotClusteredWithRegularAccesses() = runTest {
Assume.assumeTrue(SdkLevel.isAtLeastV())
val appOpEvents =
@@ -870,7 +875,10 @@ class GetPermissionGroupUsageDetailsUseCaseTest {
}
@Test
- @RequiresFlagsEnabled(Flags.FLAG_LOCATION_BYPASS_PRIVACY_DASHBOARD_ENABLED)
+ @SdkSuppress(
+ minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ codeName = "VanillaIceCream",
+ )
fun emergencyAccessesAreClustered() = runTest {
Assume.assumeTrue(SdkLevel.isAtLeastV())
val appOpEvents =
diff --git a/PermissionController/tests/permissionui/Android.bp b/PermissionController/tests/permissionui/Android.bp
index 8cc91bd99..e289e2c58 100644
--- a/PermissionController/tests/permissionui/Android.bp
+++ b/PermissionController/tests/permissionui/Android.bp
@@ -74,6 +74,7 @@ android_test {
":PermissionUiReadCalendarPermissionApp",
":PermissionUiUseLegacyBodySensorsPermissionApp",
":PermissionUiUseReadHeartRatePermissionApp",
+ ":PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App",
],
per_testcase_directory: true,
}
diff --git a/PermissionController/tests/permissionui/AndroidTest.xml b/PermissionController/tests/permissionui/AndroidTest.xml
index 9cadbd12f..85dc4925a 100644
--- a/PermissionController/tests/permissionui/AndroidTest.xml
+++ b/PermissionController/tests/permissionui/AndroidTest.xml
@@ -61,6 +61,14 @@
value="/data/local/tmp/pc-permissionui/PermissionUiUseLegacyBodySensorsPermissionApp.apk" />
<option name="push-file" key="PermissionUiUseReadHeartRatePermissionApp.apk"
value="/data/local/tmp/pc-permissionui/PermissionUiUseReadHeartRatePermissionApp.apk" />
+ <option name="push-file" key="PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App.apk"
+ value="/data/local/tmp/pc-permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App.apk" />
+ </target_preparer>
+
+ <!-- Wake the screen, and dismiss keyguard -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+ <option name="run-command" value="wm dismiss-keyguard" />
</target_preparer>
<!-- Uninstall test-apps -->
diff --git a/PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/Android.bp b/PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/Android.bp
new file mode 100644
index 000000000..539fb2686
--- /dev/null
+++ b/PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2025 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "packages_modules_Permission_PermissionController_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: [
+ "packages_modules_Permission_PermissionController_license",
+ ],
+}
+
+android_test_helper_app {
+ name: "PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App",
+
+ srcs: ["src/**/*.kt"],
+
+ sdk_version: "22",
+}
diff --git a/PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/AndroidManifest.xml b/PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/AndroidManifest.xml
new file mode 100644
index 000000000..2a08d47ae
--- /dev/null
+++ b/PermissionController/tests/permissionui/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.permissioncontroller.tests.appthatrequestpermission">
+
+ <uses-permission android:name="android.permission.BODY_SENSORS" />
+ <uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
+
+ <application />
+</manifest>
diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAllAppPermissionFragmentTest.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAllAppPermissionFragmentTest.kt
index ecc7e161f..1c6705d3e 100644
--- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAllAppPermissionFragmentTest.kt
+++ b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAllAppPermissionFragmentTest.kt
@@ -31,6 +31,7 @@ import org.junit.After
import org.junit.Assert.assertNull
import org.junit.Assume.assumeFalse
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
@@ -54,6 +55,11 @@ class HealthConnectAllAppPermissionFragmentTest : BasePermissionUiTest() {
fun uninstallTestApp() {
uninstallTestApps()
}
+
+ @SdkSuppress(
+ minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ maxSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ )
@Test
fun usedHealthConnectPermissionsAreListed() {
installTestAppThatUsesHealthConnectPermission()
@@ -67,6 +73,25 @@ class HealthConnectAllAppPermissionFragmentTest : BasePermissionUiTest() {
}
}
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
+ @Test
+ @Ignore("b/405152547")
+ fun usedHealthConnectPermissionsAreListed_healthFitnessBrand() {
+ installTestAppThatUsesHealthConnectPermission()
+
+ startManageAppPermissionsActivity()
+
+ eventually {
+ waitFindObject(By.text(HEALTH_FITNESS_LABEL))
+ waitFindObject(By.text(HEALTH_CONNECT_PERMISSION_READ_FLOORS_CLIMBED_LABEL))
+ waitFindObject(By.text(HEALTH_CONNECT_PERMISSION_READ_STEPS_LABEL))
+ }
+ }
+
+ @SdkSuppress(
+ minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ maxSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ )
@Test
fun invalidUngrantedUsedHealthConnectPermissionsAreNotListed() {
installInvalidTestAppThatUsesHealthConnectPermission()
@@ -78,13 +103,38 @@ class HealthConnectAllAppPermissionFragmentTest : BasePermissionUiTest() {
assertNull(
waitFindObjectOrNull(
By.text(HEALTH_CONNECT_PERMISSION_READ_FLOORS_CLIMBED_LABEL),
- TIMEOUT_SHORT
+ TIMEOUT_SHORT,
+ )
+ )
+ assertNull(
+ waitFindObjectOrNull(
+ By.text(HEALTH_CONNECT_PERMISSION_READ_STEPS_LABEL),
+ TIMEOUT_SHORT,
+ )
+ )
+ }
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
+ @Test
+ @Ignore("b/405152547")
+ fun invalidUngrantedUsedHealthConnectPermissionsAreNotListed_healthFitnessBrand() {
+ installInvalidTestAppThatUsesHealthConnectPermission()
+
+ startManageAppPermissionsActivity()
+
+ eventually {
+ assertNull(waitFindObjectOrNull(By.text(HEALTH_FITNESS_LABEL), TIMEOUT_SHORT))
+ assertNull(
+ waitFindObjectOrNull(
+ By.text(HEALTH_CONNECT_PERMISSION_READ_FLOORS_CLIMBED_LABEL),
+ TIMEOUT_SHORT,
)
)
assertNull(
waitFindObjectOrNull(
By.text(HEALTH_CONNECT_PERMISSION_READ_STEPS_LABEL),
- TIMEOUT_SHORT
+ TIMEOUT_SHORT,
)
)
}
@@ -104,7 +154,7 @@ class HealthConnectAllAppPermissionFragmentTest : BasePermissionUiTest() {
}
},
Until.newWindow(),
- TIMEOUT_SHORT
+ TIMEOUT_SHORT,
)
waitFindObject(By.descContains(MORE_OPTIONS)).click()
@@ -114,6 +164,7 @@ class HealthConnectAllAppPermissionFragmentTest : BasePermissionUiTest() {
companion object {
// Health connect label uses a non breaking space
private const val HEALTH_CONNECT_LABEL = "Health\u00A0Connect"
+ private const val HEALTH_FITNESS_LABEL = "Health, fitness and wellness"
private const val HEALTH_CONNECT_PERMISSION_READ_FLOORS_CLIMBED =
"android.permission.health.READ_FLOORS_CLIMBED"
private const val HEALTH_CONNECT_PERMISSION_READ_FLOORS_CLIMBED_LABEL =
diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAppPermissionFragmentTest.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAppPermissionFragmentTest.kt
index d4d4be6ec..48d14a967 100644
--- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAppPermissionFragmentTest.kt
+++ b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/HealthConnectAppPermissionFragmentTest.kt
@@ -36,6 +36,7 @@ import org.junit.After
import org.junit.Assume.assumeFalse
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
@@ -68,6 +69,10 @@ class HealthConnectAppPermissionFragmentTest : BasePermissionUiTest() {
uninstallTestApps()
}
+ @SdkSuppress(
+ minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
+ maxSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ )
@Test
fun usedHealthConnectPermissionsAreListed_handHeldDevices() {
assumeFalse(context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
@@ -78,6 +83,18 @@ class HealthConnectAppPermissionFragmentTest : BasePermissionUiTest() {
eventually { waitFindObject(By.text(HEALTH_CONNECT_LABEL)) }
}
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
+ @Test
+ @Ignore("b/405152547")
+ fun usedHealthConnectPermissionsAreListed_handHeldDevices_healthFitnessBrand() {
+ assumeFalse(context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
+ installTestAppThatUsesHealthConnectPermission()
+
+ startManageAppPermissionsActivity()
+
+ eventually { waitFindObject(By.text(HEALTH_FITNESS_LABEL)) }
+ }
+
@Test
fun invalidUngrantedUsedHealthConnectPermissionsAreNotListed_handHeldDevices() {
assumeFalse(context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
@@ -86,6 +103,7 @@ class HealthConnectAppPermissionFragmentTest : BasePermissionUiTest() {
startManageAppPermissionsActivity()
waitUntilObjectGone(By.text(HEALTH_CONNECT_LABEL), TIMEOUT_SHORT)
+ waitUntilObjectGone(By.text(HEALTH_FITNESS_LABEL), TIMEOUT_SHORT)
}
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@@ -115,25 +133,40 @@ class HealthConnectAppPermissionFragmentTest : BasePermissionUiTest() {
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@RequiresFlagsEnabled(FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED)
@Test
+ @Ignore("b/405152547")
fun startManageAppPermissionsActivity_handHeldDevices_requestLegacyBodySensorsUngranted_healthConnectShowsUp() {
assumeFalse(context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
installTestAppThatUsesLegacyBodySensorsPermissions()
startManageAppPermissionsActivity()
- eventually { waitFindObject(By.text(HEALTH_CONNECT_LABEL)) }
+ eventually { waitFindObject(By.text(HEALTH_FITNESS_LABEL)) }
}
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@RequiresFlagsEnabled(FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED)
@Test
+ @Ignore("b/405152547")
+ fun startManageAppPermissionsActivity_handHeldDevices_requestLegacyBodySensorsTargetSdk22Ungranted_healthConnectShowsUp() {
+ assumeFalse(context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
+ installTestAppThatUsesLegacyBodySensorsPermissionsTargetSdk22()
+
+ startManageAppPermissionsActivity()
+
+ eventually { waitFindObject(By.text(HEALTH_FITNESS_LABEL)) }
+ }
+
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
+ @RequiresFlagsEnabled(FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED)
+ @Test
fun startManageAppPermissionsActivity_handHeldDevices_requestReadHeartRateUngranted_healthConnectNotShowsUp() {
assumeFalse(context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
installTestAppThatUsesReadHeartRatePermissions()
startManageAppPermissionsActivity()
- waitUntilObjectGone(By.text(HEALTH_CONNECT_LABEL), TIMEOUT_SHORT)
+ waitUntilObjectGone(By.text(HEALTH_FITNESS_LABEL), TIMEOUT_SHORT)
}
private fun startManageAppPermissionsActivity() {
@@ -152,6 +185,7 @@ class HealthConnectAppPermissionFragmentTest : BasePermissionUiTest() {
private const val FITNESS_AND_WELLNESS_LABEL = "Fitness and wellness"
// Health connect label uses a non breaking space
private const val HEALTH_CONNECT_LABEL = "Health\u00A0Connect"
+ private const val HEALTH_FITNESS_LABEL = "Health, fitness and wellness"
private const val HEALTH_CONNECT_PERMISSION_READ_FLOORS_CLIMBED =
"android.permission.health.READ_FLOORS_CLIMBED"
diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/TestAppUtils.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/TestAppUtils.kt
index 8eef11e73..c3799c4c1 100644
--- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/TestAppUtils.kt
+++ b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/TestAppUtils.kt
@@ -40,6 +40,8 @@ private const val LEGACY_BODY_SENSORS_APK =
"$APK_DIRECTORY/PermissionUiUseLegacyBodySensorsPermissionApp.apk"
private const val READ_HEART_RATE_APK =
"$APK_DIRECTORY/PermissionUiUseReadHeartRatePermissionApp.apk"
+private const val LEGACY_BODY_SENSORS_TARGET_SDK_22_APK =
+ "$APK_DIRECTORY/PermissionUiUseLegacyBodySensorsPermissionTargetSdk22App.apk"
// All 4 of the AppThatUses_X_Permission(s) applications share the same package name.
private const val PERM_DEFINER_PACKAGE =
@@ -77,6 +79,8 @@ fun installTestAppThatUsesLegacyBodySensorsPermissions() = install(LEGACY_BODY_S
fun installTestAppThatUsesReadHeartRatePermissions() = install(READ_HEART_RATE_APK)
+fun installTestAppThatUsesLegacyBodySensorsPermissionsTargetSdk22() = install(LEGACY_BODY_SENSORS_TARGET_SDK_22_APK)
+
fun uninstallTestApps() {
uninstallApp(PERM_USER_PACKAGE)
uninstallApp(PERM_DEFINER_PACKAGE)
diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material2/ToggleChip.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material2/ToggleChip.kt
index de8e0542d..46a55bdc7 100644
--- a/PermissionController/wear-permission-components/src/wear.permission.components/material2/ToggleChip.kt
+++ b/PermissionController/wear-permission-components/src/wear.permission.components/material2/ToggleChip.kt
@@ -33,6 +33,7 @@ import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.text.style.Hyphens
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.wear.compose.material.ChipDefaults
@@ -78,7 +79,7 @@ fun ToggleChip(
textAlign = TextAlign.Start,
overflow = TextOverflow.Ellipsis,
maxLines = labelMaxLine ?: if (hasSecondaryLabel) 1 else 2,
- style = MaterialTheme.typography.button,
+ style = MaterialTheme.typography.button.copy(hyphens = Hyphens.Auto),
)
}
@@ -89,7 +90,7 @@ fun ToggleChip(
text = secondaryLabel,
overflow = TextOverflow.Ellipsis,
maxLines = secondaryLabelMaxLine ?: 1,
- style = MaterialTheme.typography.caption2,
+ style = MaterialTheme.typography.caption2.copy(hyphens = Hyphens.Auto),
)
}
}
diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButtonStyle.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButtonStyle.kt
index 114bcd4bc..f48d47b2c 100644
--- a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButtonStyle.kt
+++ b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButtonStyle.kt
@@ -16,6 +16,7 @@
package com.android.permissioncontroller.wear.permission.components.material3
import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
import androidx.wear.compose.material.ChipColors
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material3.ButtonColors
@@ -26,6 +27,7 @@ import com.android.permissioncontroller.wear.permission.components.material3.Wea
import com.android.permissioncontroller.wear.permission.components.material3.WearPermissionButtonStyle.Primary
import com.android.permissioncontroller.wear.permission.components.material3.WearPermissionButtonStyle.Secondary
import com.android.permissioncontroller.wear.permission.components.material3.WearPermissionButtonStyle.Transparent
+import com.android.permissioncontroller.wear.permission.components.material3.WearPermissionButtonStyle.Warning
/**
* This component is wrapper on material control colors, It applies the right colors based material
@@ -36,6 +38,7 @@ enum class WearPermissionButtonStyle {
Secondary,
Transparent,
DisabledLike,
+ Warning,
}
@Composable
@@ -45,6 +48,11 @@ internal fun WearPermissionButtonStyle.material2ChipColors(): ChipColors {
Secondary -> ChipDefaults.secondaryChipColors()
Transparent -> ChipDefaults.childChipColors()
DisabledLike -> chipDisabledColors()
+ Warning ->
+ ChipDefaults.secondaryChipColors(
+ backgroundColor =
+ Color(red = 65, green = 14, blue = 11, alpha = (0.8f * 255).toInt())
+ )
}
}
@@ -55,6 +63,11 @@ internal fun WearPermissionButtonStyle.material3ButtonColors(): ButtonColors {
Secondary -> ButtonDefaults.filledTonalButtonColors()
Transparent -> ButtonDefaults.childButtonColors()
DisabledLike -> ButtonDefaults.disabledLikeColors()
+ Warning ->
+ ButtonDefaults.buttonColors(
+ containerColor =
+ Color(red = 65, green = 14, blue = 11, alpha = (0.8f * 255).toInt())
+ )
}
}
diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffold.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffold.kt
index 208d3d6ec..87ca048bc 100644
--- a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffold.kt
+++ b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffold.kt
@@ -16,7 +16,6 @@
package com.android.permissioncontroller.wear.permission.components.material3
import android.graphics.drawable.Drawable
-import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.layout.Box
@@ -30,9 +29,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.painter.Painter
-import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
@@ -53,6 +50,7 @@ import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.foundation.lazy.rememberTransformingLazyColumnState
import androidx.wear.compose.material3.AppScaffold
import androidx.wear.compose.material3.CircularProgressIndicator
+import androidx.wear.compose.material3.Icon
import androidx.wear.compose.material3.IconButtonDefaults
import androidx.wear.compose.material3.ListHeader
import androidx.wear.compose.material3.MaterialTheme
@@ -271,6 +269,7 @@ private fun BoxScope.LazyColumnView(
titleItem(
text = title,
testTag = titleTestTag,
+ asScalingList = true,
contentPaddingValues = paddingDefaults.titlePaddingValues(subtitle == null),
)
subtitleItem(
@@ -287,6 +286,7 @@ private fun BoxScope.LazyColumnView(
ScalingLazyColumn(
contentPadding = scrollContentPadding,
state = listState as ScalingLazyListState,
+ autoCentering = null,
modifier = Modifier.background(MaterialTheme.colorScheme.background),
content = { scrollingViewContent(ScalingScopeConverter(this)) },
)
@@ -350,24 +350,25 @@ private fun ListScopeWrapper.iconItem(painter: Painter?, modifier: Modifier = Mo
painter?.let {
item {
val iconColor = WearPermissionButtonStyle.Secondary.material3ButtonColors().iconColor
- Image(
- painter = it,
- contentDescription = null,
- contentScale = ContentScale.Crop,
- modifier = modifier,
- colorFilter = ColorFilter.tint(iconColor),
- )
+ Icon(painter = it, contentDescription = null, modifier = modifier, tint = iconColor)
}
}
private fun ListScopeWrapper.titleItem(
text: String?,
+ asScalingList: Boolean,
testTag: String?,
contentPaddingValues: PaddingValues,
modifier: Modifier = Modifier,
) =
text?.let {
item(contentType = "header") {
+ val style =
+ if (asScalingList) {
+ MaterialTheme.typography.titleMedium
+ } else {
+ MaterialTheme.typography.titleLarge
+ }
ListHeader(
modifier = modifier.requiredHeightIn(1.dp), // We do not want default min height
contentPadding = contentPaddingValues,
@@ -376,7 +377,7 @@ private fun ListScopeWrapper.titleItem(
text = it,
textAlign = TextAlign.Center,
modifier = Modifier.optionalTestTag(testTag),
- style = MaterialTheme.typography.titleLarge.copy(hyphens = Hyphens.Auto),
+ style = style.copy(hyphens = Hyphens.Auto),
)
}
}
diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffoldPaddingDefaults.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffoldPaddingDefaults.kt
index 595fb50a3..01b8fc4be 100644
--- a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffoldPaddingDefaults.kt
+++ b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionScaffoldPaddingDefaults.kt
@@ -25,15 +25,15 @@ data class WearPermissionScaffoldPaddingDefaults(
private val screenHeight: Int,
) {
private val scrollContentHorizontalPadding = (screenWidth * 0.052).dp
- private val titleHorizontalPadding = (screenWidth * 0.0520).dp
- private val subtitleHorizontalPadding = (screenWidth * 0.0624).dp
+ private val titleHorizontalPadding = (screenWidth * 0.1200).dp
+ private val subtitleHorizontalPadding = (screenWidth * 0.0416).dp
private val scrollContentTopPadding = (screenHeight * 0.1664).dp
private val dialogScrollContentLargeTopPadding = (screenHeight * 0.10).dp
private val dialogScrollContentTopPadding = (screenHeight * 0.012).dp
private val scrollContentBottomPadding = (screenHeight * 0.3646).dp
private val noPadding = 0.dp
private val defaultItemPadding = 4.dp
- private val largeItemPadding = 8.dp
+ private val largeItemPadding = 12.dp
private val extraLargePadding = 12.dp
fun titlePaddingValues(needsLargePadding: Boolean): PaddingValues =
@@ -48,7 +48,7 @@ data class WearPermissionScaffoldPaddingDefaults(
PaddingValues(
start = subtitleHorizontalPadding,
top = if (needsLargePadding) extraLargePadding else noPadding,
- bottom = largeItemPadding,
+ bottom = 8.dp,
end = subtitleHorizontalPadding,
)
diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionToggleControl.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionToggleControl.kt
index 1dfb90682..7998f43de 100644
--- a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionToggleControl.kt
+++ b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionToggleControl.kt
@@ -23,8 +23,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.text.style.Hyphens
import androidx.wear.compose.material3.CheckboxButton
import androidx.wear.compose.material3.LocalTextConfiguration
+import androidx.wear.compose.material3.LocalTextStyle
import androidx.wear.compose.material3.RadioButton
import androidx.wear.compose.material3.SwitchButton
import androidx.wear.compose.material3.Text
@@ -112,6 +114,7 @@ private fun WearPermissionToggleControlInternal(
text = label,
modifier = Modifier.fillMaxWidth(),
maxLines = labelMaxLines ?: LocalTextConfiguration.current.maxLines,
+ style = LocalTextStyle.current.copy(hyphens = Hyphens.Auto),
)
}
@@ -122,6 +125,7 @@ private fun WearPermissionToggleControlInternal(
text = it,
modifier = Modifier.fillMaxWidth(),
maxLines = secondaryLabelMaxLines ?: LocalTextConfiguration.current.maxLines,
+ style = LocalTextStyle.current.copy(hyphens = Hyphens.Auto),
)
}
}
diff --git a/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml b/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml
index 4e1865697..730edf812 100644
--- a/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml
+++ b/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml
@@ -30,16 +30,6 @@
initialDisplayState="disabled"
notificationsAllowed="true"/>
<dynamic-safety-source
- id="AndroidFaceUnlock"
- packageName="com.android.settings"
- profile="all_profiles"
- title="@com.android.safetycenter.resources:string/face_unlock_title"
- titleForWork="@com.android.safetycenter.resources:string/face_unlock_title_for_work"
- titleForPrivateProfile="@com.android.safetycenter.resources:string/face_unlock_title_for_private_profile"
- searchTerms="@com.android.safetycenter.resources:string/face_unlock_search_terms"
- refreshOnPageOpenAllowed="true"
- initialDisplayState="hidden"/>
- <dynamic-safety-source
id="AndroidFingerprintUnlock"
packageName="com.android.settings"
profile="all_profiles"
@@ -50,6 +40,16 @@
refreshOnPageOpenAllowed="true"
initialDisplayState="hidden"/>
<dynamic-safety-source
+ id="AndroidFaceUnlock"
+ packageName="com.android.settings"
+ profile="all_profiles"
+ title="@com.android.safetycenter.resources:string/face_unlock_title"
+ titleForWork="@com.android.safetycenter.resources:string/face_unlock_title_for_work"
+ titleForPrivateProfile="@com.android.safetycenter.resources:string/face_unlock_title_for_private_profile"
+ searchTerms="@com.android.safetycenter.resources:string/face_unlock_search_terms"
+ refreshOnPageOpenAllowed="true"
+ initialDisplayState="hidden"/>
+ <dynamic-safety-source
id="AndroidWearUnlock"
packageName="com.android.settings"
profile="all_profiles"
diff --git a/service/java/com/android/ecm/EnhancedConfirmationService.java b/service/java/com/android/ecm/EnhancedConfirmationService.java
index 1a6b80a3c..1cc3a743e 100644
--- a/service/java/com/android/ecm/EnhancedConfirmationService.java
+++ b/service/java/com/android/ecm/EnhancedConfirmationService.java
@@ -685,7 +685,7 @@ public class EnhancedConfirmationService extends SystemService {
if (number != null && mTelephonyManager.isEmergencyNumber(number)) {
return CALL_TYPE_EMERGENCY;
}
- } catch (IllegalStateException | UnsupportedOperationException e) {
+ } catch (RuntimeException e) {
// If either of these are thrown, the telephony service is not available on the
// current device, either because the device lacks telephony calling, or the
// telephony service is unavailable.
diff --git a/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java
index 437aa19c4..ce724b13e 100644
--- a/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java
+++ b/tests/cts/permission/src/android/permission/cts/NoSystemFunctionPermissionTest.java
@@ -166,7 +166,8 @@ public class NoSystemFunctionPermissionTest extends AndroidTestCase {
*/
@SmallTest
public void testSendSms() {
- if (!getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ if (!getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEPHONY_MESSAGING)) {
return;
}
diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
index e1068e19a..0f6504502 100644
--- a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
+++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
@@ -62,13 +62,8 @@ import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = "VanillaIceCream")
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@AppModeFull(reason = "VirtualDeviceManager cannot be accessed by instant apps")
-@RequiresFlagsEnabled(
- Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
- Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES,
-)
open class DeviceAwarePermissionGrantTest {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val defaultDeviceContext = instrumentation.targetContext
@@ -273,7 +268,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
- // TODO: Receives PERMISSION_DENIED but it's fine if remote permission is held??
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun deviceAwarePermission_onRemote_requestHostPermission() {
createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
@@ -289,6 +284,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun deviceAwarePermission_onRemote_withRemotePermission_requestHostPermission() {
createVirtualDevice(cameraPolicy = DEVICE_POLICY_CUSTOM)
@@ -334,6 +330,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun deviceAwarePermissionWithoutCapability_onHost_requestRemotePermission() {
createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
@@ -349,6 +346,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun deviceAwarePermissionWithoutCapability_onRemote_requestRemotePermission() {
createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
@@ -364,6 +362,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun deviceAwarePermissionWithoutCapability_onRemote_requestPermissionWithoutDeviceId() {
createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
@@ -379,6 +378,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun deviceAwarePermissionWithoutCapability_onRemote_requestHostPermission() {
createVirtualDevice(cameraPolicy = DEVICE_POLICY_DEFAULT)
@@ -424,6 +424,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun nonDeviceAwarePermission_onHost_requestRemotePermission() {
createVirtualDevice()
@@ -439,6 +440,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun nonDeviceAwarePermission_onRemote_requestRemotePermission() {
createVirtualDevice()
@@ -454,6 +456,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun nonDeviceAwarePermission_onRemote_requestPermissionWithoutDeviceId() {
createVirtualDevice()
@@ -469,6 +472,7 @@ open class DeviceAwarePermissionGrantTest {
)
}
+ @RequiresFlagsEnabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
fun nonDeviceAwarePermission_onRemote_requestHostPermission() {
createVirtualDevice()
diff --git a/tests/cts/permissionpolicy/res/raw/android_manifest.xml b/tests/cts/permissionpolicy/res/raw/android_manifest.xml
index 2547b9786..200e3cf42 100644
--- a/tests/cts/permissionpolicy/res/raw/android_manifest.xml
+++ b/tests/cts/permissionpolicy/res/raw/android_manifest.xml
@@ -4554,12 +4554,12 @@
android:protectionLevel="signature|privileged" />
<!-- Allows application to request to stream content from an Android host to a nearby device
- ({@link android.companion.AssociationRequest#DEVICE_PROFILE_SENSOR_DEVICE_STREAMING})
+ ({@link android.companion.AssociationRequest#DEVICE_PROFILE_VIRTUAL_DEVICE})
by {@link android.companion.CompanionDeviceManager}.
<p>Not for use by third-party applications.
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE)
-->
- <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_SENSOR_DEVICE_STREAMING"
+ <permission android:name="android.permission.REQUEST_COMPANION_PROFILE_VIRTUAL_DEVICE"
android:protectionLevel="signature|privileged"
android:featureFlag="android.companion.virtualdevice.flags.enable_limited_vdm_role" />
@@ -5394,13 +5394,13 @@
corresponding permission such as {@link #HEAD_TRACKING} or
{@link #FACE_TRACKING} for the data being accessed.
- <p>Protection level: normal|appop
+ <p>Protection level: signature|privileged
@SystemApi
@FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
@hide -->
<permission android:name="android.permission.XR_TRACKING_IN_BACKGROUND"
- android:protectionLevel="normal|appop"
+ android:protectionLevel="signature|privileged"
android:description="@string/permdesc_xr_tracking_in_background"
android:label="@string/permlab_xr_tracking_in_background"
android:featureFlag="android.xr.xr_manifest_entries" />
diff --git a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt
index 9ec09137e..432d1efb1 100644
--- a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt
+++ b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt
@@ -57,6 +57,7 @@ import com.android.compatibility.common.util.UiDumpUtils
import com.android.modules.utils.build.SdkLevel
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeoutException
import java.util.regex.Pattern
import org.junit.After
import org.junit.Assert
@@ -64,7 +65,6 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
-import java.util.concurrent.TimeoutException
abstract class BaseUsePermissionTest : BasePermissionTest() {
companion object {
@@ -237,7 +237,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_PRIVACY,
PICKER_ENABLED_SETTING,
- true
+ true,
)
}
}
@@ -246,7 +246,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
enum class PermissionState {
ALLOWED,
DENIED,
- DENIED_WITH_PREJUDICE
+ DENIED_WITH_PREJUDICE,
}
private val windowManagerStateHelper = WindowManagerStateHelper()
@@ -311,7 +311,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
android.Manifest.permission.READ_MEDIA_IMAGES to
"@android:string/permgrouplab_readMediaVisual",
android.Manifest.permission.READ_MEDIA_VIDEO to
- "@android:string/permgrouplab_readMediaVisual"
+ "@android:string/permgrouplab_readMediaVisual",
)
@Before
@@ -333,7 +333,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
grantRuntimePermissions,
expectSuccess,
installSource,
- false
+ false,
)
}
@@ -350,7 +350,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
reinstall,
grantRuntimePermissions,
expectSuccess,
- installSource
+ installSource,
)
val targetSdk = getTargetSdk()
@@ -397,9 +397,9 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
uiDevice.wait(
Until.hasObject(
By.textStartsWith("This app was built for an older version of Android")
- .displayId(displayId)
+ .displayId(displayId)
),
- timeoutMillis
+ timeoutMillis,
)
if (targetSdkWarningVisible) {
try {
@@ -425,8 +425,8 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
if (isAutomotive || isWatch) {
clickAndWaitForWindowTransition(
By.text(getPermissionControllerString("review_button_continue"))
- .displayId(displayId),
- TIMEOUT_MILLIS * 2
+ .displayId(displayId),
+ TIMEOUT_MILLIS * 2,
)
} else {
clickAndWaitForWindowTransition(
@@ -452,7 +452,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
installPackageViaSession(
apkName,
AppMetadata.createDefaultAppMetadata(),
- PACKAGE_SOURCE_STORE
+ PACKAGE_SOURCE_STORE,
)
}
@@ -460,7 +460,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
installPackageViaSession(
apkName,
AppMetadata.createDefaultAppMetadata(),
- PACKAGE_SOURCE_LOCAL_FILE
+ PACKAGE_SOURCE_LOCAL_FILE,
)
}
@@ -468,18 +468,18 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
installPackageViaSession(
apkName,
AppMetadata.createDefaultAppMetadata(),
- PACKAGE_SOURCE_DOWNLOADED_FILE
+ PACKAGE_SOURCE_DOWNLOADED_FILE,
)
}
protected fun installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms(
- apkName: String,
+ apkName: String
) {
installPackageViaSession(
apkName,
AppMetadata.createDefaultAppMetadata(),
PACKAGE_SOURCE_DOWNLOADED_FILE,
- allowlistedRestrictedPermissions = SessionParams.RESTRICTED_PERMISSIONS_ALL
+ allowlistedRestrictedPermissions = SessionParams.RESTRICTED_PERMISSIONS_ALL,
)
}
@@ -487,7 +487,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
installPackageViaSession(
apkName,
AppMetadata.createDefaultAppMetadata(),
- PACKAGE_SOURCE_OTHER
+ PACKAGE_SOURCE_OTHER,
)
}
@@ -516,38 +516,38 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
protected fun installPackageWithInstallSourceAndMetadataWithoutTopLevelVersion(
- apkName: String,
+ apkName: String
) {
installPackageViaSession(
apkName,
- AppMetadata.createInvalidAppMetadataWithoutTopLevelVersion()
+ AppMetadata.createInvalidAppMetadataWithoutTopLevelVersion(),
)
}
protected fun installPackageWithInstallSourceAndMetadataWithInvalidTopLevelVersion(
- apkName: String,
+ apkName: String
) {
installPackageViaSession(
apkName,
- AppMetadata.createInvalidAppMetadataWithInvalidTopLevelVersion()
+ AppMetadata.createInvalidAppMetadataWithInvalidTopLevelVersion(),
)
}
protected fun installPackageWithInstallSourceAndMetadataWithoutSafetyLabelVersion(
- apkName: String,
+ apkName: String
) {
installPackageViaSession(
apkName,
- AppMetadata.createInvalidAppMetadataWithoutSafetyLabelVersion()
+ AppMetadata.createInvalidAppMetadataWithoutSafetyLabelVersion(),
)
}
protected fun installPackageWithInstallSourceAndMetadataWithInvalidSafetyLabelVersion(
- apkName: String,
+ apkName: String
) {
installPackageViaSession(
apkName,
- AppMetadata.createInvalidAppMetadataWithInvalidSafetyLabelVersion()
+ AppMetadata.createInvalidAppMetadataWithInvalidSafetyLabelVersion(),
)
}
@@ -557,12 +557,14 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
protected fun assertPermissionRationaleActivityTitleIsVisible(expected: Boolean) {
- findView(By.res(PERMISSION_RATIONALE_ACTIVITY_TITLE_VIEW).displayId(displayId),
- expected = expected)
+ findView(
+ By.res(PERMISSION_RATIONALE_ACTIVITY_TITLE_VIEW).displayId(displayId),
+ expected = expected,
+ )
}
protected fun assertPermissionRationaleActivityDataSharingSourceSectionVisible(
- expected: Boolean,
+ expected: Boolean
) {
findView(By.res(DATA_SHARING_SOURCE_TITLE_ID).displayId(displayId), expected = expected)
findView(By.res(DATA_SHARING_SOURCE_MESSAGE_ID).displayId(displayId), expected = expected)
@@ -579,8 +581,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
protected fun assertPermissionRationaleActivitySettingsSectionVisible(expected: Boolean) {
- findView(By.res(PERMISSION_RATIONALE_SETTINGS_SECTION).displayId(displayId),
- expected = expected)
+ findView(
+ By.res(PERMISSION_RATIONALE_SETTINGS_SECTION).displayId(displayId),
+ expected = expected,
+ )
findView(By.res(SETTINGS_TITLE_ID).displayId(displayId), expected = expected)
findView(By.res(SETTINGS_MESSAGE_ID).displayId(displayId), expected = expected)
}
@@ -599,8 +603,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
protected fun assertPermissionRationaleContainerOnGrantDialogIsVisible(expected: Boolean) {
- findView(By.res(GRANT_DIALOG_PERMISSION_RATIONALE_CONTAINER_VIEW).displayId(displayId),
- expected = expected)
+ findView(
+ By.res(GRANT_DIALOG_PERMISSION_RATIONALE_CONTAINER_VIEW).displayId(displayId),
+ expected = expected,
+ )
}
protected fun clickPermissionReviewCancel() {
@@ -645,7 +651,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
block()
assertEquals(
expectedResultCode,
- future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS).resultCode
+ future.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS).resultCode,
)
}
@@ -660,7 +666,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
component =
ComponentName(
APP_PACKAGE_NAME,
- "$APP_PACKAGE_NAME.RequestPermissionsActivity"
+ "$APP_PACKAGE_NAME.RequestPermissionsActivity",
)
putExtra("$APP_PACKAGE_NAME.PERMISSIONS", permissions)
addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK)
@@ -678,20 +684,16 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
crossinline block: () -> Unit,
): Instrumentation.ActivityResult {
// Request the permissions
- val future =
- startActivityForFuture(
- Intent().apply {
- component =
- ComponentName(
- APP_PACKAGE_NAME,
- "$APP_PACKAGE_NAME.RequestPermissionsActivity"
- )
- putExtra("$APP_PACKAGE_NAME.PERMISSIONS", permissions)
- putExtra("$APP_PACKAGE_NAME.ASK_TWICE", askTwice)
- }
- )
-
- waitForPermissionRequestActivity()
+ lateinit var future: CompletableFuture<Instrumentation.ActivityResult>
+ // The WindowManagerStateHelper#waitForValidState only supports S+
+ if (SdkLevel.isAtLeastS()) {
+ future = startActivityForFuture(*permissions, askTwice = askTwice)
+ waitForPermissionRequestActivity()
+ } else {
+ doAndWaitForWindowTransition {
+ future = startActivityForFuture(*permissions, askTwice = askTwice)
+ }
+ }
// Notification permission prompt is shown first, so get it out of the way
clickNotificationPermissionRequestAllowButtonIfAvailable()
@@ -711,9 +713,22 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
}
+ fun startActivityForFuture(
+ vararg permissions: String?,
+ askTwice: Boolean,
+ ): CompletableFuture<Instrumentation.ActivityResult> =
+ startActivityForFuture(
+ Intent().apply {
+ component =
+ ComponentName(APP_PACKAGE_NAME, "$APP_PACKAGE_NAME.RequestPermissionsActivity")
+ putExtra("$APP_PACKAGE_NAME.PERMISSIONS", permissions)
+ putExtra("$APP_PACKAGE_NAME.ASK_TWICE", askTwice)
+ }
+ )
+
/**
- * This method waits for permission controller activity to be in a valid state, the timeout
- * is 5 seconds.
+ * This method waits for permission controller activity to be in a valid state, the timeout is 5
+ * seconds.
*/
fun waitForPermissionRequestActivity() {
val requestPermissionIntent = Intent(PackageManager.ACTION_REQUEST_PERMISSIONS)
@@ -757,12 +772,12 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
*permissions,
askTwice = askTwice,
waitForWindowTransition = shouldWaitForWindowTransition,
- block = block
+ block = block,
)
assertEquals(
"Permission request result had unexpected resultCode:",
Activity.RESULT_OK,
- result.resultCode
+ result.resultCode,
)
val responseSize: Int =
@@ -770,14 +785,14 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
assertEquals(
"Permission request result had unexpected number of grant results:",
responseSize,
- result.resultData!!.getIntArrayExtra("$APP_PACKAGE_NAME.GRANT_RESULTS")!!.size
+ result.resultData!!.getIntArrayExtra("$APP_PACKAGE_NAME.GRANT_RESULTS")!!.size,
)
// Note that the behavior around requesting `null` permissions changed in the platform
// in Android U. Currently, null permissions are ignored and left out of the result set.
assertTrue(
"Permission request result had fewer permissions than request",
- permissions.size >= responseSize
+ permissions.size >= responseSize,
)
assertEquals(
"Permission request result had unexpected grant results:",
@@ -789,7 +804,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
result.resultData!!.getIntArrayExtra("$APP_PACKAGE_NAME.GRANT_RESULTS")!!.map {
it == PackageManager.PERMISSION_GRANTED
}
- )
+ ),
)
permissionAndExpectedGrantResults.forEach {
@@ -808,7 +823,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
permissionAndExpectedGrantResults,
askTwice,
waitForWindowTransition,
- block
+ block,
)
}
@@ -819,7 +834,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
!uiDevice.performActionAndWait(
{ block() },
Until.newWindow(),
- NEW_WINDOW_TIMEOUT_MILLIS
+ NEW_WINDOW_TIMEOUT_MILLIS,
)
if (timeoutOccurred) {
@@ -832,8 +847,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
protected fun findPermissionRequestAllowButton(timeoutMillis: Long = 20000) {
if (isAutomotive || isWatch) {
- waitFindObject(By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT))
- .displayId(displayId), timeoutMillis)
+ waitFindObject(
+ By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT)).displayId(displayId),
+ timeoutMillis,
+ )
} else {
waitFindObject(By.res(ALLOW_BUTTON).displayId(displayId), timeoutMillis)
}
@@ -844,8 +861,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
isHealthPermission: Boolean = false,
) {
if (isAutomotive || isWatch || isHealthPermission) {
- click(By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT)).displayId(displayId),
- timeoutMillis)
+ click(
+ By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT)).displayId(displayId),
+ timeoutMillis,
+ )
} else {
click(By.res(ALLOW_BUTTON).displayId(displayId), timeoutMillis)
}
@@ -864,14 +883,16 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
uiDevice.wait(
Until.hasObject(
By.text(getPermissionControllerString(NOTIF_TEXT, APP_PACKAGE_NAME))
- .displayId(displayId)
+ .displayId(displayId)
),
- 1000
+ 1000,
)
if (notificationPermissionRequestVisible) {
if (isAutomotive) {
- click(By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT))
- .displayId(displayId))
+ click(
+ By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT))
+ .displayId(displayId)
+ )
} else {
click(By.res(ALLOW_BUTTON).displayId(displayId))
}
@@ -887,11 +908,15 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
protected fun clickAllowAlwaysInSettings() {
if (isAutomotive || isTv || isWatch) {
- click(By.text(getPermissionControllerString("app_permission_button_allow_always"))
- .displayId(displayId))
+ click(
+ By.text(getPermissionControllerString("app_permission_button_allow_always"))
+ .displayId(displayId)
+ )
} else {
- click(By.res("com.android.permissioncontroller:id/allow_always_radio_button")
- .displayId(displayId))
+ click(
+ By.res("com.android.permissioncontroller:id/allow_always_radio_button")
+ .displayId(displayId)
+ )
}
}
@@ -901,11 +926,14 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
protected fun clicksDenyInSettings() {
if (isAutomotive || isWatch) {
- click(By.text(getPermissionControllerString("app_permission_button_deny"))
- .displayId(displayId))
+ click(
+ By.text(getPermissionControllerString("app_permission_button_deny"))
+ .displayId(displayId)
+ )
} else {
- click(By.res("com.android.permissioncontroller:id/deny_radio_button")
- .displayId(displayId))
+ click(
+ By.res("com.android.permissioncontroller:id/deny_radio_button").displayId(displayId)
+ )
}
}
@@ -913,8 +941,8 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
if (isAutomotive || isWatch) {
waitFindObject(
By.text(getPermissionControllerString(ALLOW_FOREGROUND_BUTTON_TEXT))
- .displayId(displayId),
- timeoutMillis
+ .displayId(displayId),
+ timeoutMillis,
)
} else {
waitFindObject(By.res(ALLOW_FOREGROUND_BUTTON).displayId(displayId), timeoutMillis)
@@ -925,8 +953,8 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
if (isAutomotive || isWatch) {
click(
By.text(getPermissionControllerString(ALLOW_FOREGROUND_BUTTON_TEXT))
- .displayId(displayId),
- timeoutMillis
+ .displayId(displayId),
+ timeoutMillis,
)
} else {
click(By.res(ALLOW_FOREGROUND_BUTTON).displayId(displayId), timeoutMillis)
@@ -1004,7 +1032,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
val nextScreenNode: AccessibilityNodeInfo? =
findAccessibilityNodeInfosByTextForSurfaceView(
uiAutomation.rootInActiveWindow,
- "All the time"
+ "All the time",
)
if (nextScreenNode != null) {
clickedOnLink = true
@@ -1022,9 +1050,8 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
if (!isWatch) {
// Check "Allow all" button is visible.
val allowAllNode =
- uiAutomation.rootInActiveWindow.findAccessibilityNodeInfosByText(
- HEALTH_PERMISSION_ALLOW_ALL_PLAIN_TEXT
- )[0]
+ uiAutomation.rootInActiveWindow
+ .findAccessibilityNodeInfosByText(HEALTH_PERMISSION_ALLOW_ALL_PLAIN_TEXT)[0]
assertTrue(allowAllNode.isVisibleToUser)
// Select "Heart rate" toggle and click "Allow" button.
@@ -1050,7 +1077,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
scrollToBottom()
clickAndWaitForWindowTransition(
By.text(getPermissionControllerString(DENY_AND_DONT_ASK_AGAIN_BUTTON_TEXT))
- .displayId(displayId)
+ .displayId(displayId)
)
} else if (isWatch) {
click(By.text(getPermissionControllerString(DENY_BUTTON_TEXT)).displayId(displayId))
@@ -1066,15 +1093,17 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
} else {
click(
By.res("com.android.permissioncontroller:id/permission_deny_dont_ask_again_button")
- .displayId(displayId)
+ .displayId(displayId)
)
}
}
protected fun clickPermissionRequestNoUpgradeAndDontAskAgainButton() {
if (isAutomotive || isWatch) {
- click(By.text(getPermissionControllerString(NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON_TEXT))
- .displayId(displayId))
+ click(
+ By.text(getPermissionControllerString(NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON_TEXT))
+ .displayId(displayId)
+ )
} else {
click(By.res(NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON).displayId(displayId))
}
@@ -1083,13 +1112,14 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
protected fun clickPermissionRationaleContentInAppPermission() {
clickAndWaitForWindowTransition(
By.text(getPermissionControllerString(APP_PERMISSION_RATIONALE_SUBTITLE_TEXT))
- .displayId(displayId)
+ .displayId(displayId)
)
}
protected fun clickPermissionRationaleViewInGrantDialog() {
clickAndWaitForWindowTransition(
- By.res(GRANT_DIALOG_PERMISSION_RATIONALE_CONTAINER_VIEW).displayId(displayId))
+ By.res(GRANT_DIALOG_PERMISSION_RATIONALE_CONTAINER_VIEW).displayId(displayId)
+ )
}
protected fun grantAppPermissionsByUi(vararg permissions: String) {
@@ -1109,7 +1139,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
setAppPermissionState(
*permissions,
state = PermissionState.DENIED,
- isLegacyApp = isLegacyApp
+ isLegacyApp = isLegacyApp,
)
}
@@ -1151,7 +1181,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
throw e
}
},
- TIMEOUT_MILLIS
+ TIMEOUT_MILLIS,
)
}
@@ -1164,6 +1194,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
}
}
+
protected fun navigateToIndividualPermissionSetting(
permission: String,
manuallyNavigate: Boolean = false,
@@ -1181,8 +1212,10 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
navigateToAppPermissionSettings()
val permissionLabel = getPermissionLabel(permission)
if (isWatch) {
- clickAndWaitForWindowTransition(By.text(permissionLabel).displayId(displayId),
- 40_000)
+ clickAndWaitForWindowTransition(
+ By.text(permissionLabel).displayId(displayId),
+ 40_000,
+ )
} else {
clickPermissionControllerUi(By.text(permissionLabel).displayId(displayId))
}
@@ -1280,24 +1313,28 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
// won't show an "Ask every time" message
!waitFindObject(
By.text(getPermissionControllerString("app_permission_button_deny"))
- .displayId(displayId)
+ .displayId(displayId)
)
.isChecked
} else if (isTv || isWatch) {
- !(waitFindObject(By.text(getPermissionControllerString(DENY_BUTTON_TEXT))
- .displayId(displayId))
+ !(waitFindObject(
+ By.text(getPermissionControllerString(DENY_BUTTON_TEXT))
+ .displayId(displayId)
+ )
.isChecked ||
(!isLegacyApp &&
hasAskButton(permission) &&
- waitFindObject(By.text(getPermissionControllerString(ASK_BUTTON_TEXT))
- .displayId(displayId))
+ waitFindObject(
+ By.text(getPermissionControllerString(ASK_BUTTON_TEXT))
+ .displayId(displayId)
+ )
.isChecked))
} else {
!(waitFindObject(By.res(DENY_RADIO_BUTTON).displayId(displayId)).isChecked ||
(!isLegacyApp &&
hasAskButton(permission) &&
waitFindObject(By.res(ASK_RADIO_BUTTON).displayId(displayId))
- .isChecked))
+ .isChecked))
}
var alreadyChecked = false
val button =
@@ -1309,50 +1346,55 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
PermissionState.ALLOWED ->
if (showsForegroundOnlyButton(permission)) {
By.text(
- getPermissionControllerString(
- "app_permission_button_allow_foreground"
+ getPermissionControllerString(
+ "app_permission_button_allow_foreground"
+ )
)
- ).displayId(displayId)
+ .displayId(displayId)
} else {
By.text(
- getPermissionControllerString("app_permission_button_allow")
- ).displayId(displayId)
+ getPermissionControllerString(
+ "app_permission_button_allow"
+ )
+ )
+ .displayId(displayId)
}
PermissionState.DENIED ->
By.text(getPermissionControllerString("app_permission_button_deny"))
- .displayId(displayId)
+ .displayId(displayId)
PermissionState.DENIED_WITH_PREJUDICE ->
By.text(getPermissionControllerString("app_permission_button_deny"))
- .displayId(displayId)
+ .displayId(displayId)
}
} else if (isTv || isWatch) {
when (state) {
PermissionState.ALLOWED ->
if (showsForegroundOnlyButton(permission)) {
By.text(
- getPermissionControllerString(
- ALLOW_FOREGROUND_PREFERENCE_TEXT
+ getPermissionControllerString(
+ ALLOW_FOREGROUND_PREFERENCE_TEXT
+ )
)
- ).displayId(displayId)
+ .displayId(displayId)
} else {
byAnyText(
getPermissionControllerResString(ALLOW_BUTTON_TEXT),
getPermissionControllerResString(
ALLOW_ALL_FILES_BUTTON_TEXT
- )
+ ),
)
}
PermissionState.DENIED ->
if (!isLegacyApp && hasAskButton(permission)) {
By.text(getPermissionControllerString(ASK_BUTTON_TEXT))
- .displayId(displayId)
+ .displayId(displayId)
} else {
By.text(getPermissionControllerString(DENY_BUTTON_TEXT))
- .displayId(displayId)
+ .displayId(displayId)
}
PermissionState.DENIED_WITH_PREJUDICE ->
By.text(getPermissionControllerString(DENY_BUTTON_TEXT))
- .displayId(displayId)
+ .displayId(displayId)
}
} else {
when (state) {
@@ -1370,8 +1412,8 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
} else {
By.res(DENY_RADIO_BUTTON).displayId(displayId)
}
- PermissionState.DENIED_WITH_PREJUDICE -> By.res(DENY_RADIO_BUTTON)
- .displayId(displayId)
+ PermissionState.DENIED_WITH_PREJUDICE ->
+ By.res(DENY_RADIO_BUTTON).displayId(displayId)
}
}
)
@@ -1388,8 +1430,11 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
if (isWatch) {
click(
By.desc(
- getPermissionControllerString("media_confirm_dialog_positive_button")
- ).displayId(displayId)
+ getPermissionControllerString(
+ "media_confirm_dialog_positive_button"
+ )
+ )
+ .displayId(displayId)
)
} else {
click(By.res(ALERT_DIALOG_OK_BUTTON).displayId(displayId))
@@ -1400,7 +1445,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
if (isWatch) {
waitFindObject(
By.text(getPermissionControllerString("old_sdk_deny_warning"))
- .displayId(displayId)
+ .displayId(displayId)
)
} else {
waitFindObject(By.res(ALERT_DIALOG_MESSAGE).displayId(displayId))
@@ -1421,7 +1466,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
resources.getIdentifier(
"com.android.permissioncontroller:string/grant_dialog_button_deny_anyway",
null,
- null
+ null,
)
val confirmText = resources.getString(confirmTextRes)
@@ -1447,8 +1492,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
android.Manifest.permission.RECORD_AUDIO,
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
- android.Manifest.permission.ACCESS_BACKGROUND_LOCATION,
- -> true
+ android.Manifest.permission.ACCESS_BACKGROUND_LOCATION -> true
else -> false
}
@@ -1459,8 +1503,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
return when (permission) {
Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED,
Manifest.permission.READ_MEDIA_IMAGES,
- Manifest.permission.READ_MEDIA_VIDEO,
- -> true
+ Manifest.permission.READ_MEDIA_VIDEO -> true
else -> false
}
}
@@ -1468,8 +1511,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
private fun showsForegroundOnlyButton(permission: String): Boolean =
when (permission) {
android.Manifest.permission.CAMERA,
- android.Manifest.permission.RECORD_AUDIO,
- -> true
+ android.Manifest.permission.RECORD_AUDIO -> true
else -> false
}
@@ -1515,7 +1557,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
}
private fun byTextRes(textRes: Int): BySelector =
- By.text(context.getString(textRes)).displayId(displayId)
+ By.text(context.getString(textRes)).displayId(displayId)
private fun byTextStartsWithCaseInsensitive(prefix: String): BySelector =
By.text(Pattern.compile("(?i)^${Pattern.quote(prefix)}.*$")).displayId(displayId)
@@ -1525,7 +1567,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
assertTrue(
"Invalid permission check result: $checkPermissionResult",
checkPermissionResult == PackageManager.PERMISSION_GRANTED ||
- checkPermissionResult == PackageManager.PERMISSION_DENIED
+ checkPermissionResult == PackageManager.PERMISSION_DENIED,
)
if (!expectPermission && checkPermissionResult == PackageManager.PERMISSION_GRANTED) {
Assert.fail(
@@ -1548,7 +1590,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
component =
ComponentName(
APP_PACKAGE_NAME,
- "$APP_PACKAGE_NAME.CheckCalendarAccessActivity"
+ "$APP_PACKAGE_NAME.CheckCalendarAccessActivity",
)
}
)
@@ -1558,7 +1600,7 @@ abstract class BaseUsePermissionTest : BasePermissionTest() {
assertTrue(result.resultData!!.hasExtra("$APP_PACKAGE_NAME.HAS_ACCESS"))
assertEquals(
expectAccess,
- result.resultData!!.getBooleanExtra("$APP_PACKAGE_NAME.HAS_ACCESS", false)
+ result.resultData!!.getBooleanExtra("$APP_PACKAGE_NAME.HAS_ACCESS", false),
)
}
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 e15614be2..e2310e7fb 100644
--- a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java
@@ -893,6 +893,9 @@ public class RoleManagerTest {
assertThat(privateProfile).isNotNull();
installPackage(APP_APK_PATH, privateProfile);
installPackage(APP_CLONE_APK_PATH, privateProfile);
+
+ UiAutomatorUtils.getUiDevice().waitForIdle(30 * 1000);
+
addRoleHolderAsUser(ROLE_NAME, APP_CLONE_PACKAGE_NAME, privateProfile);
sContext.startActivity(new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)