diff options
43 files changed, 514 insertions, 176 deletions
diff --git a/PermissionController/res/values-ar/strings.xml b/PermissionController/res/values-ar/strings.xml index 142070884..445c7af55 100644 --- a/PermissionController/res/values-ar/strings.xml +++ b/PermissionController/res/values-ar/strings.xml @@ -337,7 +337,7 @@ <string name="app_perms_7d_access_all_files" msgid="8246193786397635824">"تم الوصول آخر مرة بتاريخ <xliff:g id="TIME_DATE_0">%1$s</xliff:g> في <xliff:g id="TIME_DATE_1">%2$s</xliff:g> • جميع الملفات"</string> <string name="app_perms_content_provider_24h_all_files" msgid="573104317727770850">"تم الوصول في آخر 24 ساعة • كل الملفات"</string> <string name="app_perms_content_provider_7d_all_files" msgid="7962416229708835558">"تم الوصول في آخر 7 أيام • جميع الملفات"</string> - <string name="no_permissions_allowed" msgid="6081976856354669209">"لم يتم منح أي أذونات."</string> + <string name="no_permissions_allowed" msgid="6081976856354669209">"لم يتم منح أي أذونات"</string> <string name="no_permissions_denied" msgid="8159923922804043282">"لم يتم رفض أي أذونات."</string> <string name="no_apps_allowed" msgid="7718822655254468631">"لم يتم السماح لأي تطبيقات."</string> <string name="no_apps_allowed_full" msgid="8011716991498934104">"ما من تطبيقات تم منحها إذن الوصول إلى جميع الملفات."</string> diff --git a/PermissionController/res/values-ca/strings.xml b/PermissionController/res/values-ca/strings.xml index efc256729..bee1d35dc 100644 --- a/PermissionController/res/values-ca/strings.xml +++ b/PermissionController/res/values-ca/strings.xml @@ -206,7 +206,7 @@ <string name="unused_apps_label_v2" msgid="7058776770056517980">"Activitat a l\'app en pausa si no s\'usa"</string> <string name="unused_apps_label_v3" msgid="693340578642156657">"Gestiona l\'aplicació si no s\'utilitza"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Suprimeix els permisos i els fitxers temporals, i atura les notificacions"</string> - <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Suprimeix els permisos i els fitxers temporals, atura les notificacions i arxiva l\'aplicació"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Suprimeix els permisos, elimina els fitxers temporals, atura les notificacions i arxiva l\'aplicació"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Per protegir les teves dades, els permisos d\'aquesta aplicació se suprimiran si no la utilitzes durant uns mesos."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Si l\'aplicació no s\'utilitza durant uns mesos, se suprimiran els permisos següents per protegir les teves dades: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Per protegir les teves dades, s\'han suprimit els permisos de les aplicacions que no has utilitzat durant els darrers mesos."</string> diff --git a/PermissionController/res/values-et/strings.xml b/PermissionController/res/values-et/strings.xml index 2d2cdfd25..4917f776b 100644 --- a/PermissionController/res/values-et/strings.xml +++ b/PermissionController/res/values-et/strings.xml @@ -204,9 +204,9 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Eemalda load, kui rakendust ei kasutata"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Eemalda load ja vabasta ruumi"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Tegevusetuna rakenduse tegevuste peatamine"</string> - <string name="unused_apps_label_v3" msgid="693340578642156657">"Kasutamata rakenduse haldamine"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Halda kasutamata rakendusi"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Eemaldatakse load, kustutatakse ajutised failid ja peatatakse märguanded"</string> - <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Lubade eemaldamine, ajutiste failide kustutamine, märguannete peatamine ja rakenduse arhiivimine"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Eemalda load, kustuta ajutised failid, peata märguanded ja arhiivi rakendus"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Teie andmete kaitsmiseks eemaldatakse selle rakenduse load, kui seda mõne kuu jooksul ei kasutata."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Teie andmete kaitsmiseks eemaldatakse selle rakenduse järgmised load, kui rakendust mõne kuu jooksul ei kasutata: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Teie andmete kaitsmiseks eemaldati load rakendustelt, mida te ei ole mõne kuu jooksul kasutanud."</string> diff --git a/PermissionController/res/values-fa/strings.xml b/PermissionController/res/values-fa/strings.xml index a525ae20f..6a9a67315 100644 --- a/PermissionController/res/values-fa/strings.xml +++ b/PermissionController/res/values-fa/strings.xml @@ -414,9 +414,9 @@ <string name="phone_call_uses_microphone" msgid="233569591461187177">"در <b>تماس تلفنی</b> از میکروفون استفاده میشود"</string> <string name="phone_call_uses_microphone_and_camera" msgid="6291898755681748189">"در <b>تماس تصویری</b> از دوربین و میکروفون استفاده میشود"</string> <string name="phone_call_uses_camera" msgid="2048417022147857418">"در <b>تماس تصویری</b> از دوربین استفاده میشود"</string> - <string name="system_uses_microphone" msgid="576672130318877143">"سرویس سیستم به میکروفون دسترسی دارد"</string> - <string name="system_uses_microphone_and_camera" msgid="5124478304275138804">"سرویس سیستم به دوربین و میکروفون دسترسی دارد"</string> - <string name="system_uses_camera" msgid="1911223105234441470">"سرویس سیستم به دوربین دسترسی دارد"</string> + <string name="system_uses_microphone" msgid="576672130318877143">"خدمات سیستم به میکروفون دسترسی دارد"</string> + <string name="system_uses_microphone_and_camera" msgid="5124478304275138804">"خدمات سیستم به دوربین و میکروفون دسترسی دارد"</string> + <string name="system_uses_camera" msgid="1911223105234441470">"خدمات سیستم به دوربین دسترسی دارد"</string> <string name="other_use" msgid="6564855051022776692">"استفادههای دیگر:"</string> <string name="ongoing_usage_dialog_ok" msgid="103556809118460072">"متوجه شدم"</string> <string name="ongoing_usage_dialog_title" msgid="683836493556628569">"استفاده اخیر از <xliff:g id="TYPES_LIST">%s</xliff:g>"</string> diff --git a/PermissionController/res/values-hu/strings.xml b/PermissionController/res/values-hu/strings.xml index 66597ce82..943418f1e 100644 --- a/PermissionController/res/values-hu/strings.xml +++ b/PermissionController/res/values-hu/strings.xml @@ -204,7 +204,7 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Engedélyek eltávolítása, ha nem használja az alkalmazást"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Engedélytörlés és tárhely-felszabadítás"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"App szüneteltetése, ha nem használja"</string> - <string name="unused_apps_label_v3" msgid="693340578642156657">"Használaton kívüli alkalmazás kezelése"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Nem használt alkalmazás kezelése"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Engedélyek eltávolítása, ideiglenes fájlok törlése és értesítések leállítása"</string> <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Engedélyek eltávolítása, ideiglenes fájlok törlése, értesítések leállítása és az alkalmazás archiválása"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Az adatok védelme érdekében az ennek az alkalmazásnak adott engedélyek visszavonásra kerülnek, ha néhány hónapon át nem használja az alkalmazást."</string> diff --git a/PermissionController/res/values-in/strings.xml b/PermissionController/res/values-in/strings.xml index a41fe862d..b79dc1b78 100644 --- a/PermissionController/res/values-in/strings.xml +++ b/PermissionController/res/values-in/strings.xml @@ -50,12 +50,12 @@ <string name="permission_revoked_all" msgid="3397649017727222283">"semua dinonaktifkan"</string> <string name="permission_revoked_none" msgid="9213345075484381180">"tidak ada yang dinonaktifkan"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"Izinkan"</string> - <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Izinkan sepanjang waktu"</string> + <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"Selalu izinkan"</string> <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"Saat aplikasi digunakan"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"Ubah ke lokasi presisi"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"Tetap gunakan perkiraan"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"Hanya kali ini"</string> - <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"Izinkan sepanjang waktu"</string> + <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"Selalu izinkan"</string> <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"Izinkan pengelolaan semua file"</string> <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"Izinkan akses ke file media"</string> <string name="app_permissions_breadcrumb" msgid="5136969550489411650">"Aplikasi"</string> @@ -109,7 +109,7 @@ <!-- no translation found for background_access_chooser_dialog_choices:0 (1351721623256561996) --> <!-- no translation found for background_access_chooser_dialog_choices:1 (9127301153688725448) --> <!-- no translation found for background_access_chooser_dialog_choices:2 (4305536986042401191) --> - <string name="permission_access_always" msgid="1474641821883823446">"Izinkan sepanjang waktu"</string> + <string name="permission_access_always" msgid="1474641821883823446">"Selalu izinkan"</string> <string name="permission_access_only_foreground" msgid="7801170728159326195">"Izinkan saat aplikasi digunakan"</string> <string name="permission_access_never" msgid="4647014230217936900">"Jangan izinkan"</string> <string name="loading" msgid="4789365003890741082">"Memuat…"</string> @@ -186,8 +186,8 @@ <string name="app_permission_button_allow" msgid="5808039516494774647">"Izinkan"</string> <string name="app_permission_button_allow_all_files" msgid="1792232272599018825">"Izinkan pengelolaan semua file"</string> <string name="app_permission_button_allow_media_only" msgid="2834282724426046154">"Izinkan akses hanya ke media"</string> - <string name="app_permission_button_allow_always" msgid="4573292371734011171">"Izinkan sepanjang waktu"</string> - <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"Izinkan hanya saat aplikasi digunakan"</string> + <string name="app_permission_button_allow_always" msgid="4573292371734011171">"Selalu izinkan"</string> + <string name="app_permission_button_allow_foreground" msgid="1991570451498943207">"Izinkan saat aplikasi digunakan"</string> <string name="app_permission_button_always_allow_all" msgid="4905699259378428855">"Selalu izinkan semua"</string> <string name="app_permission_button_ask" msgid="3342950658789427">"Selalu tanya"</string> <string name="app_permission_button_deny" msgid="6016454069832050300">"Jangan izinkan"</string> @@ -206,7 +206,7 @@ <string name="unused_apps_label_v2" msgid="7058776770056517980">"Jeda aktivitas aplikasi jika tak dipakai"</string> <string name="unused_apps_label_v3" msgid="693340578642156657">"Kelola aplikasi jika tidak digunakan"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Hapus izin dan file sementara, serta hentikan notifikasi"</string> - <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Menghapus izin dan file sementara, menghentikan notifikasi, serta mengarsipkan aplikasi"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Hapus izin dan file sementara, hentikan notifikasi, dan arsipkan aplikasi"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Untuk melindungi data Anda, izin aplikasi ini akan dihapus jika aplikasi tidak digunakan dalam beberapa bulan."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Untuk melindungi data Anda, izin berikut akan dihapus jika aplikasi tidak digunakan dalam beberapa bulan: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Untuk melindungi data Anda, izin dari aplikasi yang tidak digunakan dalam beberapa bulan telah dihapus."</string> diff --git a/PermissionController/res/values-ja/strings.xml b/PermissionController/res/values-ja/strings.xml index c551c7ebe..b599bd0cc 100644 --- a/PermissionController/res/values-ja/strings.xml +++ b/PermissionController/res/values-ja/strings.xml @@ -56,8 +56,8 @@ <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"おおよその位置情報を保持"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"今回のみ"</string> <string name="grant_dialog_button_allow_background" msgid="8236044729434367833">"常に許可"</string> - <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"すべてのファイルの管理を許可"</string> - <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"メディア ファイルへのアクセスを許可"</string> + <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"すべての管理を許可"</string> + <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"アクセスのみ許可"</string> <string name="app_permissions_breadcrumb" msgid="5136969550489411650">"アプリ"</string> <string name="app_permissions" msgid="3369917736607944781">"アプリの権限"</string> <string name="unused_apps" msgid="2058057455175955094">"使用されていないアプリ"</string> @@ -86,7 +86,7 @@ <string name="app_permissions_group_summary" msgid="8788419008958284002">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> 個のアプリを許可"</string> <string name="app_permissions_group_summary2" msgid="4329922444840521150">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> 件のアプリを許可"</string> <string name="menu_show_system" msgid="4254021607027872504">"システムアプリを表示"</string> - <string name="menu_hide_system" msgid="3855390843744028465">"システムアプリを表示しない"</string> + <string name="menu_hide_system" msgid="3855390843744028465">"システムアプリを非表示"</string> <string name="menu_show_7_days_data" msgid="8979611198508523706">"過去 7 日間を表示"</string> <string name="menu_show_24_hours_data" msgid="8228054833323380780">"過去 24 時間を表示"</string> <string name="manage_permission" msgid="2895385393037061964">"権限の管理"</string> diff --git a/PermissionController/res/values-pt-rPT/strings.xml b/PermissionController/res/values-pt-rPT/strings.xml index 787399bcf..4e2529ad2 100644 --- a/PermissionController/res/values-pt-rPT/strings.xml +++ b/PermissionController/res/values-pt-rPT/strings.xml @@ -206,7 +206,7 @@ <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausar atividade de apps, se não usadas"</string> <string name="unused_apps_label_v3" msgid="693340578642156657">"Gerir app, se não for usada"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remova autorizações, elimine ficheiros temporários e pare notificações"</string> - <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remova autorizações, elimine ficheiros temporários, pare notificações e arquive a app"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove autorizações, elimina ficheiros temporários, pára notificações e arquiva a app"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Para proteger os seus dados, as autorizações desta app serão removidas se a mesma não for utilizada durante alguns meses."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Para proteger os seus dados, se a app não for utilizada há alguns meses, serão removidas as seguintes autorizações: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Para proteger os seus dados, foram removidas as autorizações para as apps que não utiliza há alguns meses."</string> diff --git a/PermissionController/res/values-sv/strings.xml b/PermissionController/res/values-sv/strings.xml index 53cb70695..723a38ed8 100644 --- a/PermissionController/res/values-sv/strings.xml +++ b/PermissionController/res/values-sv/strings.xml @@ -204,7 +204,7 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"Ta bort behörigheter om en app inte används"</string> <string name="unused_apps_label" msgid="2595428768404901064">"Ta bort behörigheter och frigör utrymme"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"Pausa appaktivitet om appen inte används"</string> - <string name="unused_apps_label_v3" msgid="693340578642156657">"Hantera appen om den är oanvänd"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"Hantera appen om den inte används"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Ta bort behörigheter, radera tillfälliga filer och hindra aviseringar"</string> <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Ta bort behörigheter, radera tillfälliga filer, hindra aviseringar och arkivera appen"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Behörigheter tas bort av säkerhetsskäl från den här appen om den inte används på några månader."</string> diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt index 826e57ece..40ee75636 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageDetailsViewModel.kt @@ -32,6 +32,7 @@ import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle import android.os.UserHandle +import android.os.UserManager import androidx.annotation.RequiresApi import androidx.lifecycle.AbstractSavedStateViewModelFactory import androidx.lifecycle.SavedStateHandle @@ -85,6 +86,8 @@ class PermissionUsageDetailsViewModel( private val roleManager = Utils.getSystemServiceSafe(application.applicationContext, RoleManager::class.java) + private val userManager = + Utils.getSystemServiceSafe(application.applicationContext, UserManager::class.java) /** Updates whether system app permissions usage should be displayed in the UI. */ fun updateShowSystemAppsToggle(showSystem: Boolean) { @@ -191,6 +194,7 @@ class PermissionUsageDetailsViewModel( ): List<AppPermissionAccessUiInfo> { return allLightHistoricalPackageOpsLiveData .getLightHistoricalPackageOps() + ?.filter { Utils.shouldShowInSettings(it.userHandle, userManager) } ?.flatMap { it.clusterAccesses(startTime, showSystem) } ?.sortedBy { -1 * it.discreteAccesses.first().accessTimeMs } ?.map { it.buildAppPermissionAccessUiInfo() } @@ -488,7 +492,8 @@ class PermissionUsageDetailsViewModel( ?.let { getPackageLabel( it.proxy!!.packageName!!, - UserHandle.getUserHandleForUid(it.proxy.uid)) + UserHandle.getUserHandleForUid(it.proxy.uid) + ) } /** Returns the attribution label for the permission access, if any. */ diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageViewModel.kt index fa5b1b685..fc8deab79 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/v31/PermissionUsageViewModel.kt @@ -22,6 +22,7 @@ import android.app.role.RoleManager import android.os.Build import android.os.Bundle import android.os.UserHandle +import android.os.UserManager import androidx.annotation.RequiresApi import androidx.lifecycle.AbstractSavedStateViewModelFactory import androidx.lifecycle.AndroidViewModel @@ -55,6 +56,8 @@ class PermissionUsageViewModel( private val state: SavedStateHandle, app: Application, ) : AndroidViewModel(app) { + private val userManager = + Utils.getSystemServiceSafe(app.applicationContext, UserManager::class.java) private val roleManager = Utils.getSystemServiceSafe(app.applicationContext, RoleManager::class.java) private val exemptedPackages: Set<String> = Utils.getExemptedPackages(roleManager) @@ -114,7 +117,10 @@ class PermissionUsageViewModel( } val eligibleLightPackageOpsList: List<LightPackageOps> = - getAllLightPackageOps()?.filterOutExemptedApps() ?: listOf() + getAllLightPackageOps()?.filterOutExemptedApps()?.filter { + Utils.shouldShowInSettings(it.userHandle, userManager) + } + ?: listOf() for (lightPackageOps: LightPackageOps in eligibleLightPackageOpsList) { val permGroupsToLastAccess: List<Map.Entry<String, Long>> = diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java index fdeb2ed2a..5f23829b0 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/ReviewPermissionsWearFragment.java @@ -179,7 +179,10 @@ public class ReviewPermissionsWearFragment extends PreferenceFragmentCompat } else { preference.setEnabled(true); } - + if (preference.getParent() != null) { + // Remove first if already added. + preference.getParent().removePreference(preference); + } if (group.isReviewRequired()) { if (!isPackageUpdated) { // An app just being installed, which means all groups requiring reviews. diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt index bc840bac9..0883666fc 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt @@ -35,7 +35,7 @@ import com.android.permissioncontroller.permission.ui.wear.model.RevokeDialogArg @Composable fun WearAppPermissionGroupsScreen(helper: WearAppPermissionGroupsHelper) { - val packagePermGroups = helper.viewModel.packagePermGroupsLiveData.observeAsState(emptyMap()) + val packagePermGroups = helper.viewModel.packagePermGroupsLiveData.observeAsState(null) val autoRevoke = helper.viewModel.autoRevokeLiveData.observeAsState(null) val appPermissionUsages = helper.wearViewModel.appPermissionUsages.observeAsState(emptyList()) val showRevokeDialog = helper.revokeDialogViewModel.showDialogLiveData.observeAsState(false) @@ -53,7 +53,7 @@ fun WearAppPermissionGroupsScreen(helper: WearAppPermissionGroupsHelper) { ) } - if (isLoading && packagePermGroups.value.isNotEmpty()) { + if (isLoading && !packagePermGroups.value.isNullOrEmpty()) { isLoading = false } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java index 2c36c0adc..dffc49aa2 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java @@ -68,6 +68,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; +import android.content.pm.UserProperties; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.Bitmap; @@ -1591,4 +1592,30 @@ public final class Utils { @NonNull ApplicationInfo applicationInfo) { return context.getPackageManager().getApplicationLabel(applicationInfo).toString(); } + + /** + * Returns whether the given user should be shown in the Settings UI in SdkLevel V+. This method + * will always return true for SdkLevels below V. + * + * @param userHandle The user for which to check whether it should be shown or not. + * @return true if it should be shown, false otherwise. + */ + public static boolean shouldShowInSettings(UserHandle userHandle, UserManager userManager) { + return !SdkLevel.isAtLeastV() || shouldShowInSettingsInternal(userHandle, userManager); + } + + /** + * Returns whether the given user should be shown in the Settings UI. + * + * @param userHandle The user for which to check whether it should be shown or not. + * @return true if it should be shown, false otherwise. + */ + @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.VANILLA_ICE_CREAM) + private static boolean shouldShowInSettingsInternal( + UserHandle userHandle, UserManager userManager) { + var userProperties = userManager.getUserProperties(userHandle); + return !userManager.isQuietModeEnabled(userHandle) + || userProperties.getShowInQuietMode() != UserProperties.SHOW_IN_QUIET_MODE_HIDDEN; + } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreference.java index e6bc9bab6..71b0ef98b 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreference.java @@ -16,15 +16,24 @@ package com.android.permissioncontroller.role.ui; +import android.os.UserHandle; + +import androidx.annotation.NonNull; import androidx.annotation.Nullable; /** - * Preference that is aware of user restrictions that can block them. + * Preference that is aware of restrictions that can block them. */ -public interface UserRestrictionAwarePreference { +public interface RestrictionAwarePreference { /** * Specifies user restriction that blocks this preference. */ - void setUserRestriction(@Nullable String userRestriction); + void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user); + + /** + * Specifies enhanced confirmation restrictions that block this preference. + */ + void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user); } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreferenceMixin.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreferenceMixin.java new file mode 100644 index 000000000..81908de16 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RestrictionAwarePreferenceMixin.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.role.ui; + +import android.app.PendingIntent; +import android.app.admin.DevicePolicyManager; +import android.app.ecm.EnhancedConfirmationManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.modules.utils.build.SdkLevel; +import com.android.permissioncontroller.DeviceUtils; +import com.android.permissioncontroller.role.utils.UserUtils; + +/** + * Mixin for implementing {@link RestrictionAwarePreference}. + */ +public class RestrictionAwarePreferenceMixin { + + private static final String LOG_TAG = RestrictionAwarePreferenceMixin.class.getSimpleName(); + + @NonNull + private final Preference mPreference; + + @Nullable + private String mUserRestriction; + + @Nullable + private String mEnhancedConfirmationRestrictedPackageName; + @Nullable + private String mEnhancedConfirmationRestrictedSettingIdentifier; + + @Nullable + private UserHandle mUser; + + public RestrictionAwarePreferenceMixin(@NonNull Preference preference) { + mPreference = preference; + } + + /** + * Implementation for {@link RestrictionAwarePreference#setUserRestriction}. + */ + public void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user) { + mUserRestriction = userRestriction; + mUser = user; + updateEnabled(); + } + + /** + * Implementation for {@link RestrictionAwarePreference#setEnhancedConfirmationRestriction}. + */ + public void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user) { + if (!isEnhancedConfirmationRestrictionEnabled()) { + return; + } + mEnhancedConfirmationRestrictedPackageName = packageName; + mEnhancedConfirmationRestrictedSettingIdentifier = settingIdentifier; + mUser = user; + updateEnabled(); + } + + private boolean isEnhancedConfirmationRestrictionEnabled() { + // Enhanced confirmation restriction is currently applied only to handheld. + Context context = mPreference.getContext(); + return !(DeviceUtils.isAuto(context) || DeviceUtils.isTelevision(context) + || DeviceUtils.isWear(context)); + } + + private void updateEnabled() { + mPreference.setEnabled(mUserRestriction == null + && (mEnhancedConfirmationRestrictedPackageName == null + || mEnhancedConfirmationRestrictedSettingIdentifier == null)); + } + + /** + * Call after {@link Preference#onBindViewHolder} to apply blocking effects. + */ + public void onAfterBindViewHolder(@NonNull PreferenceViewHolder holder) { + View.OnClickListener onClickListener = null; + if (SdkLevel.isAtLeastV() + && mEnhancedConfirmationRestrictedPackageName != null + && mEnhancedConfirmationRestrictedSettingIdentifier != null + && mUser != null) { + Context context = UserUtils.getUserContext(holder.itemView.getContext(), mUser); + onClickListener = (view) -> { + try { + context.getSystemService(EnhancedConfirmationManager.class) + .getRestrictedSettingDialogIntent( + mEnhancedConfirmationRestrictedPackageName, + mEnhancedConfirmationRestrictedSettingIdentifier) + .send(); + } catch (PendingIntent.CanceledException e) { + Log.e(LOG_TAG, "Pending intent fail to be sent.", e); + } catch (PackageManager.NameNotFoundException e) { + Log.e(LOG_TAG, "Package name is not found.", e); + } + }; + } else if (mUserRestriction != null) { + Intent userRestrictionIntent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS) + .putExtra(DevicePolicyManager.EXTRA_RESTRICTION, mUserRestriction); + onClickListener = (view) -> { + holder.itemView.getContext().startActivity(userRestrictionIntent); + }; + } + + // We set the item view to enabled to make the preference row clickable. + // Normal disabled preferences have the whole view hierarchy disabled, so by making only + // the top-level itemView enabled, we don't change the fact that the whole preference + // still "looks" disabled (see Preference.onBindViewHolder). + // Preference.onBindViewHolder sets the onClickListener as well on each preference, so + // we don't need to unset the listener here (we wouldn't know the correct one anyway). + // This approach is used already by com.android.settingslib.RestrictedPreferenceHelper. + if (onClickListener != null) { + holder.itemView.setEnabled(true); + holder.itemView.setOnClickListener(onClickListener); + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java index 1b5b27971..1d3e32c9c 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java @@ -22,7 +22,7 @@ import androidx.preference.TwoStatePreference; /** * Preference for application being a candidate or holding a role. */ -public interface RoleApplicationPreference extends UserRestrictionAwarePreference { +public interface RoleApplicationPreference extends RestrictionAwarePreference { /** * Get instance of {@code this} as {@link TwoStatePreference}. diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java index 442963ce6..becbbea62 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java @@ -21,7 +21,7 @@ import androidx.preference.Preference; /** * Preference used by the default apps list UI. */ -public interface RolePreference extends TwoTargetPreference, UserRestrictionAwarePreference { +public interface RolePreference extends TwoTargetPreference, RestrictionAwarePreference { /** * Return this preference as {@link Preference}. */ diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java b/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java deleted file mode 100644 index 033507991..000000000 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/UserRestrictionAwarePreferenceMixin.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.permissioncontroller.role.ui; - -import android.app.admin.DevicePolicyManager; -import android.content.Intent; -import android.provider.Settings; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.preference.Preference; -import androidx.preference.PreferenceViewHolder; - -/** - * Mixin for implementing {@link UserRestrictionAwarePreference}. - */ -public class UserRestrictionAwarePreferenceMixin { - - @NonNull - private final Preference mPreference; - @Nullable - private String mUserRestriction = null; - - public UserRestrictionAwarePreferenceMixin(@NonNull Preference preference) { - mPreference = preference; - } - - /** - * Implementation for {@link UserRestrictionAwarePreference#setUserRestriction}. - */ - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestriction = userRestriction; - mPreference.setEnabled(mUserRestriction == null); - } - - /** - * Call after {@link Preference#onBindViewHolder} to apply blocking effects. - */ - public void onAfterBindViewHolder(@NonNull PreferenceViewHolder holder) { - if (mUserRestriction != null) { - // We set the item view to enabled to make the preference row clickable. - // Normal disabled preferences have the whole view hierarchy disabled, so by making only - // the top-level itemView enabled, we don't change the fact that the whole preference - // still "looks" disabled (see Preference.onBindViewHolder). - // Preference.onBindViewHolder sets the onClickListener as well on each preference, so - // we don't need to unset the listener here (we wouldn't know the correct one anyway). - // This approach is used already by com.android.settingslib.RestrictedPreferenceHelper. - holder.itemView.setEnabled(true); - Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS) - .putExtra(DevicePolicyManager.EXTRA_RESTRICTION, mUserRestriction); - holder.itemView.setOnClickListener( - (view) -> holder.itemView.getContext().startActivity(intent)); - } - } -} diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java index 83c146ebc..ebeba0482 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java @@ -17,23 +17,25 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; +import android.os.UserHandle; import android.widget.RadioButton; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.res.TypedArrayUtils; import androidx.preference.PreferenceViewHolder; import androidx.preference.TwoStatePreference; import com.android.permissioncontroller.R; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; /** Preference used to represent apps that can be picked as a default app. */ public class AutoRadioPreference extends TwoStatePreference implements RoleApplicationPreference { - private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public AutoRadioPreference(Context context) { super(context, null, @@ -54,12 +56,19 @@ public class AutoRadioPreference extends TwoStatePreference implements RadioButton radioButton = (RadioButton) holder.findViewById(R.id.radio_button); radioButton.setChecked(isChecked()); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction, user); + } + + @Override + public void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setEnhancedConfirmationRestriction(packageName, + settingIdentifier, user); } @Override diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java index d2f1b6cde..af4f0cc0a 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; +import android.os.UserHandle; import android.util.AttributeSet; import androidx.annotation.NonNull; @@ -24,9 +25,9 @@ import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RolePreference; import com.android.permissioncontroller.role.ui.TwoTargetPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; /** * Preference for use in auto lists. Extends {@link TwoTargetPreference} in order to make sure of @@ -34,8 +35,8 @@ import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMi */ public class AutoRolePreference extends Preference implements RolePreference { - private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public AutoRolePreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -60,15 +61,22 @@ public class AutoRolePreference extends Preference implements RolePreference { } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction, user); + } + + @Override + public void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setEnhancedConfirmationRestriction(packageName, + settingIdentifier, user); } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @Override diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java index 900e58551..a21bc8d8b 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; +import android.os.UserHandle; import android.util.AttributeSet; import androidx.annotation.AttrRes; @@ -26,8 +27,8 @@ import androidx.annotation.StyleRes; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; /** * Role application preference represented as a switch. @@ -35,8 +36,8 @@ import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMi public class AutoSwitchPreference extends SwitchPreference implements RoleApplicationPreference { - private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public AutoSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { @@ -57,15 +58,22 @@ public class AutoSwitchPreference extends SwitchPreference } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction, user); + } + + @Override + public void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setEnhancedConfirmationRestriction(packageName, + settingIdentifier, user); } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @NonNull diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java index d9ef047d6..4c7d636d7 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java @@ -17,14 +17,15 @@ package com.android.permissioncontroller.role.ui.handheld; import android.content.Context; +import android.os.UserHandle; import android.util.AttributeSet; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceViewHolder; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; import com.android.settingslib.widget.SelectorWithWidgetPreference; /** @@ -33,8 +34,8 @@ import com.android.settingslib.widget.SelectorWithWidgetPreference; public class HandheldRadioPreference extends SelectorWithWidgetPreference implements RoleApplicationPreference { - private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public HandheldRadioPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) { @@ -55,16 +56,22 @@ public class HandheldRadioPreference extends SelectorWithWidgetPreference implem } @Override - public void setUserRestriction( - @Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction, user); + } + + @Override + public void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setEnhancedConfirmationRestriction(packageName, + settingIdentifier, user); } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @NonNull diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java index 978fe7d5a..270e3a928 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui.handheld; import android.content.Context; +import android.os.UserHandle; import android.util.AttributeSet; import android.view.View; @@ -28,8 +29,8 @@ import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import com.android.permissioncontroller.R; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RolePreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; import com.android.settingslib.widget.TwoTargetPreference; /** @@ -40,8 +41,8 @@ import com.android.settingslib.widget.TwoTargetPreference; // Made public for com.android.permissioncontroller.role.ui.specialappaccess.handheld public class HandheldRolePreference extends TwoTargetPreference implements RolePreference { - private final UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); @Nullable private OnSecondTargetClickListener mOnSecondTargetClickListener; @@ -93,8 +94,15 @@ public class HandheldRolePreference extends TwoTargetPreference implements RoleP } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction, user); + } + + @Override + public void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setEnhancedConfirmationRestriction(packageName, + settingIdentifier, user); } @Override @@ -113,7 +121,7 @@ public class HandheldRolePreference extends TwoTargetPreference implements RoleP // Make the settings button enabled even if the preference itself is disabled. settingsButton.setEnabled(true); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @Override diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java index 1b4dd78a4..d5081566d 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/specialappaccess/handheld/HandheldSwitchPreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui.specialappaccess.handheld; import android.content.Context; +import android.os.UserHandle; import android.util.AttributeSet; import androidx.annotation.AttrRes; @@ -25,16 +26,16 @@ import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.preference.PreferenceViewHolder; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreferenceMixin; import com.android.settingslib.widget.AppSwitchPreference; /** {@link AppSwitchPreference} that is a role application preference. */ public class HandheldSwitchPreference extends AppSwitchPreference implements RoleApplicationPreference { - private UserRestrictionAwarePreferenceMixin mUserRestrictionAwarePreferenceMixin = - new UserRestrictionAwarePreferenceMixin(this); + private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = + new RestrictionAwarePreferenceMixin(this); public HandheldSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { @@ -55,15 +56,22 @@ public class HandheldSwitchPreference extends AppSwitchPreference } @Override - public void setUserRestriction(@Nullable String userRestriction) { - mUserRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction); + public void setUserRestriction(@Nullable String userRestriction, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setUserRestriction(userRestriction, user); + } + + @Override + public void setEnhancedConfirmationRestriction(@Nullable String packageName, + @Nullable String settingIdentifier, @NonNull UserHandle user) { + mRestrictionAwarePreferenceMixin.setEnhancedConfirmationRestriction(packageName, + settingIdentifier, user); } @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); - mUserRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @NonNull diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt index 29f90ddc3..430860bbb 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui.wear import android.app.admin.DevicePolicyManager import android.content.Context import android.content.Intent +import android.os.UserHandle import android.provider.Settings import androidx.preference.TwoStatePreference import com.android.permissioncontroller.role.ui.RoleApplicationPreference @@ -32,7 +33,8 @@ class WearRoleApplicationPreference( val label: String, val checked: Boolean, val onDefaultCheckChanged: (Boolean) -> Unit = {}, - private var restriction: String? = null + private var restriction: String? = null, + private var user: UserHandle? = null ) : TwoStatePreference(context), RoleApplicationPreference { fun getOnCheckChanged(): (Boolean) -> Unit = restriction?.let { @@ -45,11 +47,21 @@ class WearRoleApplicationPreference( } ?: onDefaultCheckChanged - override fun setUserRestriction(userRestriction: String?) { + override fun setUserRestriction(userRestriction: String?, userHandle: UserHandle) { restriction = userRestriction + user = userHandle setEnabled(restriction == null) } + override fun setEnhancedConfirmationRestriction( + packageName: String?, + settingIdentifier: String?, + user: UserHandle + ) { + // no-op because Enhanced Confirmation Restriction is not applied to wear yet. + return + } + override fun asTwoStatePreference(): TwoStatePreference { return this } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt index 16d35ed76..9acaa158d 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRolePreference.kt @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui.wear import android.app.admin.DevicePolicyManager import android.content.Context import android.content.Intent +import android.os.UserHandle import android.provider.Settings import androidx.preference.Preference import com.android.permissioncontroller.role.ui.RolePreference @@ -30,18 +31,29 @@ class WearRolePreference( context: Context, val label: String, val onDefaultClicked: () -> Unit = {}, - private var restriction: String? = null + private var restriction: String? = null, + private var user: UserHandle? = null ) : TwoTargetPreference(context), RolePreference { override fun setOnSecondTargetClickListener(listener: OnSecondTargetClickListener?) { // no-op } - override fun setUserRestriction(userRestriction: String?) { + override fun setUserRestriction(userRestriction: String?, userHandle: UserHandle) { restriction = userRestriction + user = userHandle setEnabled(restriction == null) } + override fun setEnhancedConfirmationRestriction( + packageName: String?, + settingIdentifier: String?, + user: UserHandle + ) { + // no-op because Enhanced Confirmation Restriction is not applied to wear yet. + return + } + override fun asPreference(): Preference { return this } diff --git a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java index 5114af536..175bd71e5 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java +++ b/PermissionController/src/com/android/permissioncontroller/role/utils/RoleUiBehaviorUtils.java @@ -16,20 +16,23 @@ package com.android.permissioncontroller.role.utils; +import android.app.ecm.EnhancedConfirmationManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.UserHandle; import android.os.UserManager; +import android.permission.flags.Flags; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.modules.utils.build.SdkLevel; +import com.android.permissioncontroller.role.ui.RestrictionAwarePreference; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; import com.android.permissioncontroller.role.ui.RolePreference; -import com.android.permissioncontroller.role.ui.UserRestrictionAwarePreference; import com.android.permissioncontroller.role.ui.behavior.RoleUiBehavior; import com.android.role.controller.model.Role; @@ -99,7 +102,8 @@ public final class RoleUiBehaviorUtils { @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user, @NonNull Context context) { prepareUserRestrictionAwarePreferenceAsUser(role, preference, user, context); - + prepareEnhancedConfirmationRestrictionAwarePreferenceAsUser(role, preference, + applicationInfo.packageName, user, context); RoleUiBehavior uiBehavior = getUiBehavior(role); if (uiBehavior == null) { return; @@ -110,15 +114,52 @@ public final class RoleUiBehaviorUtils { } private static void prepareUserRestrictionAwarePreferenceAsUser(@NonNull Role role, - @NonNull UserRestrictionAwarePreference preference, @NonNull UserHandle user, + @NonNull RestrictionAwarePreference preference, @NonNull UserHandle user, @NonNull Context context) { if (SdkLevel.isAtLeastU() && role.isExclusive()) { UserManager userManager = context.getSystemService(UserManager.class); boolean hasDisallowConfigDefaultApps = userManager.hasUserRestrictionForUser( UserManager.DISALLOW_CONFIG_DEFAULT_APPS, user); preference.setUserRestriction(hasDisallowConfigDefaultApps - ? UserManager.DISALLOW_CONFIG_DEFAULT_APPS : null); + ? UserManager.DISALLOW_CONFIG_DEFAULT_APPS : null, user); + } + } + + private static void prepareEnhancedConfirmationRestrictionAwarePreferenceAsUser( + @NonNull Role role, @NonNull RestrictionAwarePreference preference, + @NonNull String packageName, @NonNull UserHandle user, @NonNull Context context) { + if (isEnhancedConfirmationRestrictedAsUser(packageName, role.getName(), user, context)) { + preference.setEnhancedConfirmationRestriction(packageName, role.getName(), user); + } else { + preference.setEnhancedConfirmationRestriction(null, null, user); + } + } + + /** + * This method checks if the package is restricted from a specific role with the given user. + * + * @param packageName the package name to check for + * @param user the user to check for + * @param context the {@code Context} to retrieve system services + * + * @return whether the package is restricted for a role + */ + private static boolean isEnhancedConfirmationRestrictedAsUser(@NonNull String packageName, + @NonNull String roleName, @NonNull UserHandle user, @NonNull Context context) { + if (SdkLevel.isAtLeastV() + && Flags.enhancedConfirmationModeApisEnabled()) { + Context userContext = UserUtils.getUserContext(context, user); + EnhancedConfirmationManager enhancedConfirmationManager = + userContext.getSystemService(EnhancedConfirmationManager.class); + try { + if (enhancedConfirmationManager.isRestricted(packageName, roleName)) { + return true; + } + } catch (PackageManager.NameNotFoundException e) { + Log.w(LOG_TAG, "Cannot find package name:" + packageName, e); + } } + return false; } /** diff --git a/SafetyCenter/Resources/res/values-de-v35/strings.xml b/SafetyCenter/Resources/res/values-de-v35/strings.xml index b3573e2a8..3cff5bf65 100644 --- a/SafetyCenter/Resources/res/values-de-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-de-v35/strings.xml @@ -19,7 +19,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="cellular_network_security_title" msgid="2986431282931510973">"Sicherheit von Mobilfunknetzen"</string> <string name="cellular_network_security_summary" msgid="7319307247487475572">"Netzwerktyp, Verschlüsselung, Benachrichtigungseinstellungen"</string> - <string name="private_space_title" msgid="6158245041481535879">"Privater Bereich"</string> + <string name="private_space_title" msgid="6158245041481535879">"Privates Profil"</string> <string name="private_space_summary" msgid="529869826714610294">"Privaten Bereich einrichten und mehr"</string> - <string name="private_space_search_terms" msgid="4820808478299116258">"Privater Bereich"</string> + <string name="private_space_search_terms" msgid="4820808478299116258">"Privates Profil"</string> </resources> diff --git a/SafetyCenter/Resources/res/values-ja/strings.xml b/SafetyCenter/Resources/res/values-ja/strings.xml index 6e67998f4..b31b1690a 100644 --- a/SafetyCenter/Resources/res/values-ja/strings.xml +++ b/SafetyCenter/Resources/res/values-ja/strings.xml @@ -30,9 +30,9 @@ <string name="permission_usage_title" msgid="3633779688945350407">"プライバシー ダッシュボード"</string> <string name="permission_usage_summary" msgid="5323079206029964468">"権限を最近使用したアプリが表示されます"</string> <string name="permission_usage_search_terms" msgid="3852343592870257104">"プライバシー, プライバシー ダッシュボード"</string> - <string name="permission_manager_title" msgid="5277347862821255015">"権限マネージャー"</string> + <string name="permission_manager_title" msgid="5277347862821255015">"権限マネージャ"</string> <string name="permission_manager_summary" msgid="8099852107340970790">"アプリのデータアクセスを管理します"</string> - <string name="permission_manager_search_terms" msgid="2895147613099694722">"権限, 権限マネージャー"</string> + <string name="permission_manager_search_terms" msgid="2895147613099694722">"権限, 権限マネージャ"</string> <string name="privacy_controls_title" msgid="5322875777945432395">"プライバシー管理"</string> <string name="privacy_controls_summary" msgid="2402066941190435424">"マイク、カメラなどへのデバイス アクセスを管理します"</string> <string name="privacy_controls_search_terms" msgid="3774472175934304165">"プライバシー, プライバシー管理"</string> diff --git a/framework-s/api/system-current.txt b/framework-s/api/system-current.txt index 3712eae97..61af606e9 100644 --- a/framework-s/api/system-current.txt +++ b/framework-s/api/system-current.txt @@ -7,6 +7,7 @@ package android.app.ecm { method @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) public boolean isClearRestrictionAllowed(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; method @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) public boolean isRestricted(@NonNull String, @NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; method @RequiresPermission(android.Manifest.permission.MANAGE_ENHANCED_CONFIRMATION_STATES) public void setClearRestrictionAllowed(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + field public static final String ACTION_SHOW_ECM_RESTRICTED_SETTING_DIALOG = "android.app.ecm.action.SHOW_ECM_RESTRICTED_SETTING_DIALOG"; } } diff --git a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java index 52e220bc0..86aa222c6 100644 --- a/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java +++ b/framework-s/java/android/app/ecm/EnhancedConfirmationManager.java @@ -16,9 +16,12 @@ package android.app.ecm; +import static android.annotation.SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION; + import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.RequiresPermission; +import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TargetApi; @@ -37,6 +40,7 @@ import android.util.ArraySet; import androidx.annotation.NonNull; import java.lang.annotation.Retention; +import java.util.concurrent.atomic.AtomicInteger; /** * This class provides the core API for ECM (Enhanced Confirmation Mode). ECM is a feature that @@ -192,6 +196,13 @@ public final class EnhancedConfirmationManager { * appropriate RequiresPermission annotation. */ + /** + * Shows the "Restricted setting" dialog. Opened when a setting is blocked. + */ + @SdkConstant(BROADCAST_INTENT_ACTION) + public static final String ACTION_SHOW_ECM_RESTRICTED_SETTING_DIALOG = + "android.app.ecm.action.SHOW_ECM_RESTRICTED_SETTING_DIALOG"; + /** A map of ECM states to their corresponding app op states */ @Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix = {"ECM_STATE_"}, value = {EcmState.ECM_STATE_NOT_GUARDED, @@ -218,6 +229,8 @@ public final class EnhancedConfirmationManager { private final @NonNull IEnhancedConfirmationManager mService; + private static final AtomicInteger sNextRequestCode = new AtomicInteger(1); + /** * @hide */ @@ -335,8 +348,8 @@ public final class EnhancedConfirmationManager { Intent intent = new Intent(Settings.ACTION_SHOW_RESTRICTED_SETTING_DIALOG); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); intent.putExtra(Intent.EXTRA_UID, getPackageUid(packageName)); - // TODO(b/323225971): Pass settingIdentifier to dialog - return PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE); + return PendingIntent.getActivity(mContext, sNextRequestCode.getAndIncrement(), + intent, PendingIntent.FLAG_IMMUTABLE); } private int getPackageUid(String packageName) throws NameNotFoundException { diff --git a/framework/java/android/permission/PermissionState.java b/framework/java/android/permission/PermissionStateUnused.java index e810db8ec..21b21cc27 100644 --- a/framework/java/android/permission/PermissionState.java +++ b/framework/java/android/permission/PermissionStateUnused.java @@ -19,4 +19,4 @@ package android.permission; /** * @hide */ -public class PermissionState {} +public class PermissionStateUnused {} diff --git a/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt b/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt index c67707f5f..579b03f9c 100644 --- a/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt +++ b/tests/cts/permission/src/android/permission/cts/RevokePermissionTest.kt @@ -50,15 +50,6 @@ class RevokePermissionTest { @Test @AppModeFull(reason = "Instant apps can't revoke permissions.") - fun testRevokePermissionNotRequested() { - testRevoke( - packageName = APP_PKG_NAME, - permission = CAMERA - ) - } - - @Test - @AppModeFull(reason = "Instant apps can't revoke permissions.") fun testRevokeFakePermission() { val fakePermissionName = "FAKE_PERMISSION" testRevoke( @@ -94,16 +85,6 @@ class RevokePermissionTest { @Test @AppModeFull(reason = "Instant apps can't revoke permissions.") - fun testRevokePermissionNotRequestedWithReason() { - testRevoke( - packageName = APP_PKG_NAME, - permission = CAMERA, - reason = "test reason" - ) - } - - @Test - @AppModeFull(reason = "Instant apps can't revoke permissions.") fun testRevokeFakePermissionWithReason() { val fakePermissionName = "FAKE_PERMISSION" testRevoke( diff --git a/tests/cts/permissionmultidevice/AndroidManifest.xml b/tests/cts/permissionmultidevice/AndroidManifest.xml index e7c993d57..9bad85813 100644 --- a/tests/cts/permissionmultidevice/AndroidManifest.xml +++ b/tests/cts/permissionmultidevice/AndroidManifest.xml @@ -20,6 +20,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="android.permissionmultidevice.cts"> + <uses-feature android:name="android.software.companion_device_setup" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> diff --git a/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt b/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt index 0eff95a3d..e8d35e614 100644 --- a/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt +++ b/tests/cts/permissionmultidevice/TestUtils/src/android/permissionmultidevice/cts/FakeVirtualDeviceRule.kt @@ -26,6 +26,7 @@ class FakeVirtualDeviceRule : FakeAssociationRule() { private lateinit var virtualDeviceManager: VirtualDeviceManager lateinit var virtualDevice: VirtualDeviceManager.VirtualDevice + lateinit var deviceDisplayName: String var virtualDisplayId: Int = -1 override fun before() { @@ -57,6 +58,10 @@ class FakeVirtualDeviceRule : FakeAssociationRule() { ) Truth.assertThat(display).isNotNull() virtualDisplayId = display!!.display.displayId + deviceDisplayName = + virtualDeviceManager + .getDisplayNameForPersistentDeviceId(virtualDevice.persistentDeviceId!!) + .toString() } } diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt index 09f4c7f08..b3efa36cb 100644 --- a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt +++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt @@ -94,7 +94,7 @@ class DeviceAwarePermissionGrantTest { Display.DEFAULT_DISPLAY, mFakeVirtualDeviceRule.virtualDevice.deviceId, true, - DEFAULT_REMOTE_DEVICE_NAME, + mFakeVirtualDeviceRule.deviceDisplayName, expectPermissionGrantedOnDefaultDevice = false, expectPermissionGrantedOnRemoteDevice = true ) @@ -120,7 +120,7 @@ class DeviceAwarePermissionGrantTest { mFakeVirtualDeviceRule.virtualDisplayId, mFakeVirtualDeviceRule.virtualDevice.deviceId, true, - DEFAULT_REMOTE_DEVICE_NAME, + mFakeVirtualDeviceRule.deviceDisplayName, expectPermissionGrantedOnDefaultDevice = false, expectPermissionGrantedOnRemoteDevice = true ) @@ -199,7 +199,6 @@ class DeviceAwarePermissionGrantTest { const val APP_APK_PATH_STREAMING = "${APK_DIRECTORY}/CtsAccessRemoteDeviceCamera.apk" const val APP_PACKAGE_NAME = "android.permissionmultidevice.cts.accessremotedevicecamera" const val PERMISSION_MESSAGE_ID = "com.android.permissioncontroller:id/permission_message" - const val DEFAULT_REMOTE_DEVICE_NAME = "remote device" const val ALLOW_BUTTON = "com.android.permissioncontroller:id/permission_allow_foreground_only_button" const val DEVICE_ID_DEFAULT = 0 diff --git a/tests/cts/permissionpolicy/res/raw/android_manifest.xml b/tests/cts/permissionpolicy/res/raw/android_manifest.xml index cb02e0536..7231a1838 100644 --- a/tests/cts/permissionpolicy/res/raw/android_manifest.xml +++ b/tests/cts/permissionpolicy/res/raw/android_manifest.xml @@ -843,6 +843,19 @@ android:description="@string/permdesc_writeContacts" android:protectionLevel="dangerous" /> + <!-- Allows an app to update the verification status of E2EE contact keys owned by other apps. + <p>This permission is only granted to system apps. + <p>Protection level: signature|privileged + @SystemApi + @hide + @FlaggedApi("android.provider.user_keys") + --> + <permission android:name="android.permission.WRITE_VERIFICATION_STATE_E2EE_CONTACT_KEYS" + android:permissionGroup="android.permission-group.UNDEFINED" + android:label="@string/permlab_writeVerificationStateE2eeContactKeys" + android:description="@string/permdesc_writeVerificationStateE2eeContactKeys" + android:protectionLevel="signature|privileged" /> + <!-- Allows an application to set default account for new contacts. <p> This permission is only granted to system applications fulfilling the Contacts app role. <p>Protection level: internal|role @@ -2543,6 +2556,13 @@ android:description="@string/permdesc_detectScreenCapture" android:protectionLevel="normal" /> + <!-- Allows an application to get notified when it is being recorded. + <p>Protection level: normal + @FlaggedApi("com.android.window.flags.screen_recording_callbacks") + --> + <permission android:name="android.permission.DETECT_SCREEN_RECORDING" + android:protectionLevel="normal" /> + <!-- ======================================== --> <!-- Permissions for factory reset protection --> <!-- ======================================== --> @@ -3088,6 +3108,13 @@ android:description="@string/permdesc_accessHiddenProfile" android:protectionLevel="normal" /> + <!-- @SystemApi @hide Allows privileged applications to get details about hidden profile + users. + @FlaggedApi("android.multiuser.flags.enable_permission_to_access_hidden_profiles") --> + <permission + android:name="android.permission.ACCESS_HIDDEN_PROFILES_FULL" + android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows configuring apps to have the INTERACT_ACROSS_PROFILES permission so that they can interact across profiles in the same profile group. @hide --> diff --git a/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt index 83f53b252..42017a51e 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt @@ -32,6 +32,7 @@ import androidx.test.platform.app.InstrumentationRegistry import com.android.compatibility.common.util.SystemUtil.eventually import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotEquals import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test @@ -119,6 +120,19 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() { } } + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @Test + fun getRestrictedSettingDialogIntentReturnsUniqueObjects() { + installPackageWithInstallSourceAndMetadataFromDownloadedFile(apkName) + + val pendingIntent1 = + ecm.getRestrictedSettingDialogIntent(APP_PACKAGE_NAME, PROTECTED_SETTING) + val pendingIntent2 = + ecm.getRestrictedSettingDialogIntent(APP_PACKAGE_NAME, PROTECTED_SETTING) + + assertNotEquals(pendingIntent1, pendingIntent2) + } + companion object { private const val NON_PROTECTED_SETTING = "example_setting_which_is_not_protected" private const val PROTECTED_SETTING = "android:bind_accessibility_service" diff --git a/tests/cts/role/Android.bp b/tests/cts/role/Android.bp index a2e3255c3..cf6b7ee8c 100644 --- a/tests/cts/role/Android.bp +++ b/tests/cts/role/Android.bp @@ -28,6 +28,7 @@ android_test { ], static_libs: [ + "android.permission.flags-aconfig-java", "androidx.test.rules", "compatibility-device-util-axt", "ctstestrunner-axt", 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 c4fa9be93..c53718ba4 100644 --- a/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java +++ b/tests/cts/role/src/android/app/role/cts/RoleManagerTest.java @@ -27,9 +27,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import android.app.Activity; +import android.app.AppOpsManager; import android.app.Instrumentation; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; @@ -41,6 +43,10 @@ import android.content.pm.PermissionInfo; import android.os.Build; import android.os.Process; import android.os.UserHandle; +import android.permission.flags.Flags; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.provider.Telephony; import android.util.Pair; @@ -56,6 +62,7 @@ import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.UiObjectNotFoundException; +import androidx.test.uiautomator.Until; import com.android.compatibility.common.util.DisableAnimationRule; import com.android.compatibility.common.util.FreezeRotationRule; @@ -126,9 +133,14 @@ public class RoleManagerTest { private static final Context sContext = InstrumentationRegistry.getTargetContext(); private static final PackageManager sPackageManager = sContext.getPackageManager(); private static final RoleManager sRoleManager = sContext.getSystemService(RoleManager.class); + private static final boolean sIsAutomotive = sPackageManager.hasSystemFeature( + PackageManager.FEATURE_AUTOMOTIVE); + private static final boolean sIsTelevision = sPackageManager.hasSystemFeature( + PackageManager.FEATURE_TELEVISION); private static final boolean sIsWatch = sPackageManager.hasSystemFeature( PackageManager.FEATURE_WATCH); - + @Rule + public CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Rule public DisableAnimationRule mDisableAnimationRule = new DisableAnimationRule(); @@ -624,6 +636,32 @@ public class RoleManagerTest { } @Test + @RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) + @FlakyTest(bugId = 288468003, detail = "CtsRoleTestCases is breaching 20min SLO") + public void openDefaultAppDetailsOnHandHeldThenRestrictedAppIsNotSelectableAsDefaultApp() + throws Exception { + assumeFalse(sIsWatch || sIsAutomotive || sIsTelevision); + runWithShellPermissionIdentity( + () -> setEnhancedConfirmationRestrictedAppOpMode(sContext, APP_PACKAGE_NAME, + AppOpsManager.MODE_ERRORED)); + + runWithShellPermissionIdentity(() -> sContext.startActivity(new Intent( + Intent.ACTION_MANAGE_DEFAULT_APP) + .addCategory(Intent.CATEGORY_DEFAULT) + .putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NAME) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK))); + + waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).enabled(false).checked( + false)).hasDescendant(By.text(APP_LABEL))).clickAndWait(Until.newWindow(), + TIMEOUT_MILLIS); + + waitFindObject(By.textContains("Restricted setting"), UNEXPECTED_TIMEOUT_MILLIS); + + pressBack(); + } + + @Test @FlakyTest(bugId = 288468003, detail = "CtsRoleTestCases is breaching 20min SLO") public void openDefaultAppDetailsAndSetDefaultAppThenIsDefaultApp() throws Exception { runWithShellPermissionIdentity(() -> sContext.startActivity(new Intent( @@ -677,8 +715,8 @@ public class RoleManagerTest { if (sIsWatch) { waitFindObject(By.clickable(true).checked(false)).click(); } else { - waitFindObject( - By.clickable(true).hasDescendant(By.checkable(true).checked(false))).click(); + waitFindObject(By.clickable(true).hasDescendant(By.checkable(true).enabled(true) + .checked(false))).click(); } if (sIsWatch) { @@ -771,6 +809,15 @@ public class RoleManagerTest { pressBack(); } + private void setEnhancedConfirmationRestrictedAppOpMode(@NonNull Context context, + @NonNull String packageName, int mode) + throws PackageManager.NameNotFoundException { + AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class); + appOpsManager.setMode(AppOpsManager.OPSTR_ACCESS_RESTRICTED_SETTINGS, + context.getPackageManager().getApplicationInfo(packageName, 0).uid, + packageName, mode); + } + private static void waitForIdle() { UiAutomatorUtils.getUiDevice().waitForIdle(); } diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt index 0f1356ca4..6afcff85a 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt @@ -23,6 +23,7 @@ import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCE_ID import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCE_ISSUE_ID import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.compatibility.common.util.UiAutomatorUtils2 import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterActivity import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterQsActivity import com.android.safetycenter.testing.SafetyCenterActivityLauncher.openPageAndExit @@ -34,6 +35,7 @@ import com.android.safetycenter.testing.SafetyCenterTestRule import com.android.safetycenter.testing.SafetySourceTestData import com.android.safetycenter.testing.SafetySourceTestData.Companion.INFORMATION_ISSUE_ID import com.android.safetycenter.testing.UiTestHelper.waitAllTextDisplayed +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -63,6 +65,14 @@ class SafetyCenterInteractionLoggingHelperTests { SafetyCenterFlags.showSubpages = true } + @After + fun tearDown() { + // When an assertion fails, it will end up leaving the previous view open, which screws + // with the logging assertions made by this test (polluting with view events from whatever + // view was left open). Here we preemptively clear whatever's open to get back to home + UiAutomatorUtils2.getUiDevice().pressHome() + } + @Test fun openSafetyCenter() { context.launchSafetyCenterActivity {} @@ -74,7 +84,7 @@ class SafetyCenterInteractionLoggingHelperTests { safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue) context.launchSafetyCenterQsActivity { - openPageAndExit("Settings") { waitAllTextDisplayed("OK") } + openPageAndExit("Settings") { waitAllTextDisplayed(safetySourceTestData.informationIssue.title) } } } diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt index 91222d045..42a2a8a89 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt @@ -34,6 +34,7 @@ import java.security.MessageDigest import org.junit.After import org.junit.Assume.assumeTrue import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -90,6 +91,7 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { } } + @Ignore // TODO: b/323269529 - Deflake this test @Test fun openSafetyCenterFullFromQs_recordsViewEventWithCorrectSource() { helperAppRule.runTest(TEST_CLASS_NAME, "openSafetyCenterFullFromQs") |