diff options
42 files changed, 460 insertions, 130 deletions
diff --git a/PermissionController/res/values-ar/strings.xml b/PermissionController/res/values-ar/strings.xml index d0bccee97..90fce2d06 100644 --- a/PermissionController/res/values-ar/strings.xml +++ b/PermissionController/res/values-ar/strings.xml @@ -580,7 +580,7 @@ <string name="security_settings" msgid="3808106921175271317">"إعدادات الأمان"</string> <string name="sensor_permissions_qs" msgid="1022267900031317472">"الأذونات"</string> <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"الأمان والخصوصية"</string> - <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"فحص الحالة"</string> + <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"التحقّق من الحالة"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"عناصر التحكّم في خصوصيتك"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"إعدادات إضافية"</string> <string name="camera_toggle_label_qs" msgid="3880261453066157285">"الوصول إلى الكاميرا"</string> diff --git a/PermissionController/res/values-b+sr+Latn/strings.xml b/PermissionController/res/values-b+sr+Latn/strings.xml index 546b3183b..6dd7a9cb6 100644 --- a/PermissionController/res/values-b+sr+Latn/strings.xml +++ b/PermissionController/res/values-b+sr+Latn/strings.xml @@ -474,7 +474,7 @@ <string name="permgrouprequest_location" msgid="6990232580121067883">"Želite da dozvolite da aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa lokaciji ovog uređaja?"</string> <string name="permgrouprequest_device_aware_location" msgid="6075412127429878638">"Dozvoljavate da aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa lokaciji uređaja <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Aplikacija će imati pristup lokaciji samo dok koristite aplikaciju"</string> - <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Želite da dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa lokaciji ovog uređaja?"</string> + <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Želite da dozvolite da aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa lokaciji ovog uređaja?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="1264484517831380016">"Dozvoljavate da aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pristupa lokaciji uređaja <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgroupbackgroundrequestdetail_location" msgid="8021219324989662957">"Ova aplikacija možda želi da pristupa lokaciji sve vreme, čak i kada ne koristite aplikaciju. "<annotation id="link">"Dozvolite u podešavanjima."</annotation></string> <string name="permgroupupgraderequest_location" msgid="8328408946822691636">"Želite li da promenite pristup lokaciji za aplikaciju <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>?"</string> diff --git a/PermissionController/res/values-bg/strings.xml b/PermissionController/res/values-bg/strings.xml index b3c16b703..9bd171db2 100644 --- a/PermissionController/res/values-bg/strings.xml +++ b/PermissionController/res/values-bg/strings.xml @@ -60,7 +60,7 @@ <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="app_permissions" msgid="3369917736607944781">"Разрешения за приложението"</string> <string name="unused_apps" msgid="2058057455175955094">"Неизползвани приложения"</string> <string name="edit_photos_description" msgid="5540108003480078892">"Редактиране на избраните снимки за това приложение"</string> <string name="no_unused_apps" msgid="12809387670415295">"Няма неизползвани приложения"</string> @@ -195,7 +195,7 @@ <string name="app_permission_button_allow_limited_access" msgid="8824410215149764113">"Разрешаване на ограничения достъп"</string> <string name="precise_image_description" msgid="6349638632303619872">"Точно местоположение"</string> <string name="approximate_image_description" msgid="938803699637069884">"Приблизително местоположение"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Използване на точното местоположение"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Използване на точното местоположение"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Когато точното местоположение е изключено, приложенията могат да осъществяват достъп до приблизителното ви местоположение"</string> <string name="app_permission_title" msgid="2090897901051370711">"Разрешение за: <xliff:g id="PERM">%1$s</xliff:g>"</string> <string name="app_permission_header" msgid="2951363137032603806">"Достъп до „<xliff:g id="PERM">%1$s</xliff:g>“ за това приложение"</string> @@ -471,7 +471,7 @@ <string name="permgrouprequest_device_aware_storage_isolated" msgid="6463062962458809752">"Да се разреши ли на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да осъществява достъп до снимките и мултимедията на <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Да се разреши ли на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да осъществява достъп до контактите ви?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="731025863972535928">"Да се разреши ли на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да осъществява достъп до контактите ви на <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_location" msgid="6990232580121067883">"Да се разреши ли на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да осъществява достъп до местоположението на това устройство?"</string> + <string name="permgrouprequest_location" msgid="6990232580121067883">"Да се разреши ли на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да получи достъп до местоположението на това устройство?"</string> <string name="permgrouprequest_device_aware_location" msgid="6075412127429878638">"Да се разреши ли на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да осъществява достъп до местоположението на <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Само когато използвате приложението, то ще има достъп до местоположението"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Да се разреши ли на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да осъществява достъп до местоположението на това устройство?"</string> diff --git a/PermissionController/res/values-bs/strings.xml b/PermissionController/res/values-bs/strings.xml index 9dbaca940..fe036961d 100644 --- a/PermissionController/res/values-bs/strings.xml +++ b/PermissionController/res/values-bs/strings.xml @@ -683,7 +683,7 @@ <string name="enhanced_confirmation_dialog_learn_more" msgid="5226619861379095709">"Saznajte više"</string> <string name="enhanced_confirmation_dialog_ok" msgid="8560373821598619924">"Uredu"</string> <string name="permission_grant_dialog_streaming_blocked_title" msgid="8905241017017043649">"Zahtjev za odobrenje je potisnut"</string> - <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prijenosa. Najprije dajte odobrenje na telefonu."</string> + <string name="permission_grant_dialog_streaming_blocked_description" msgid="838165608934085319">"Aplikacija traži dodatna odobrenja, ali se ona ne mogu dati u sesiji prenosa. Najprije dajte odobrenje na telefonu."</string> <string name="privacy_dashboard_emergency_location_enforced_attribution_label" msgid="5702912511473457693">"Za hitni poziv ili poruku"</string> <string name="privacy_dashboard_emergency_location_dialog_title" msgid="849723944428031911">"Lokacija je poslana hitnim službama"</string> <string name="privacy_dashboard_emergency_location_dialog_description" msgid="5815970230573483329">"Ova aplikacija je pristupila lokaciji uređaja tokom poziva ili slanja poruke broju za hitne slučajeve. To se može dogoditi čak i kada aplikacija nema odobrenje za lokaciju ili je lokacija uređaja isključena. "<a href="https://support.google.com/android/answer/9319337">"Saznajte više"</a></string> diff --git a/PermissionController/res/values-ca/strings.xml b/PermissionController/res/values-ca/strings.xml index 20ca0abed..1de8e07e6 100644 --- a/PermissionController/res/values-ca/strings.xml +++ b/PermissionController/res/values-ca/strings.xml @@ -471,7 +471,7 @@ <string name="permgrouprequest_device_aware_storage_isolated" msgid="6463062962458809752">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a les fotos i al contingut multimèdia del dispositiu <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi als contactes?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="731025863972535928">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi als contactes del dispositiu <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_location" msgid="6990232580121067883">"Vols permetre que la <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu?"</string> + <string name="permgrouprequest_location" msgid="6990232580121067883">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu?"</string> <string name="permgrouprequest_device_aware_location" msgid="6075412127429878638">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"L\'aplicació només tindrà accés a la ubicació quan l\'estiguis utilitzant"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> accedeixi a la ubicació del dispositiu?"</string> diff --git a/PermissionController/res/values-el/strings.xml b/PermissionController/res/values-el/strings.xml index e8afe33f3..e000a2ac2 100644 --- a/PermissionController/res/values-el/strings.xml +++ b/PermissionController/res/values-el/strings.xml @@ -499,7 +499,7 @@ <string name="permgrouprequest_storage_pre_q" msgid="168130651144569428">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση σε <b>φωτογραφίες, βίντεο, μουσική, ήχο και άλλα αρχεία</b> της συσκευής;"</string> <string name="permgrouprequest_read_media_aural" msgid="2593365397347577812">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση στη μουσική και στα αρχεία ήχου αυτής της συσκευής;"</string> <string name="permgrouprequest_device_aware_read_media_aural" msgid="7927884506238101064">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση σε μουσική και σε ήχο στη συσκευή <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>;"</string> - <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"Να επιτρέπεται στην <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση στις φωτογραφίες και τα βίντεο αυτής της συσκευής;"</string> + <string name="permgrouprequest_read_media_visual" msgid="5548780620779729975">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση στις φωτογραφίες και τα βίντεο αυτής της συσκευής;"</string> <string name="permgrouprequest_device_aware_read_media_visual" msgid="3122576538319059333">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση σε φωτογραφίες και σε βίντεο στη συσκευή <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>;"</string> <string name="permgrouprequest_more_photos" msgid="128933814654231321">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση σε περισσότερες φωτογραφίες και βίντεο αυτής της συσκευής;"</string> <string name="permgrouprequest_device_aware_more_photos" msgid="1703469013613723053">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> η πρόσβαση σε περισσότερες φωτογραφίες και βίντεο στη συσκευή <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>;"</string> diff --git a/PermissionController/res/values-eu/strings.xml b/PermissionController/res/values-eu/strings.xml index 7acae1dbc..139f41668 100644 --- a/PermissionController/res/values-eu/strings.xml +++ b/PermissionController/res/values-eu/strings.xml @@ -357,7 +357,7 @@ <string name="role_assistant_short_label" msgid="3369003713187703399">"Laguntzaile digitalaren aplikazioa"</string> <string name="role_assistant_description" msgid="6622458130459922952">"Ikusten ari zaren pantailako informazioaren araberako laguntza eskain diezazukete laguntza-aplikazioek. Zenbait aplikaziok exekutatzeko tresna eta ahots bidezko zerbitzuak onartzen dituzte laguntza integratua eskaintzeko."</string> <string name="role_browser_label" msgid="2877796144554070207">"Arakatzaile lehenetsia"</string> - <string name="role_browser_short_label" msgid="6745009127123292296">"Arakatzaile- aplikazioa"</string> + <string name="role_browser_short_label" msgid="6745009127123292296">"Arakatzaile-apliU+2060kazioa"</string> <string name="role_browser_description" msgid="3465253637499842671">"Interneteko sarbidea ematen dizuten eta sakatzen dituzun estekak bistaratzen dituzten aplikazioak"</string> <string name="role_browser_request_title" msgid="2895200507835937192">"<xliff:g id="APP_NAME">%1$s</xliff:g> ezarri nahi duzu arakatzaile lehenetsi gisa?"</string> <string name="role_browser_request_description" msgid="5888803407905985941">"Ez du behar baimenik"</string> diff --git a/PermissionController/res/values-fr/strings.xml b/PermissionController/res/values-fr/strings.xml index 2ea77b4f4..14c29125e 100644 --- a/PermissionController/res/values-fr/strings.xml +++ b/PermissionController/res/values-fr/strings.xml @@ -60,7 +60,7 @@ <string name="grant_dialog_button_allow_all_files" msgid="4955436994954829894">"Autoriser la gestion de tous les fichiers"</string> <string name="grant_dialog_button_allow_media_only" msgid="4832877658422573832">"Autoriser l\'accès aux fichiers multimédias"</string> <string name="app_permissions_breadcrumb" msgid="5136969550489411650">"Applications"</string> - <string name="app_permissions" msgid="3369917736607944781">"Autorisations des applications"</string> + <string name="app_permissions" msgid="3369917736607944781">"Autorisations de l\'application"</string> <string name="unused_apps" msgid="2058057455175955094">"Applications inutilisées"</string> <string name="edit_photos_description" msgid="5540108003480078892">"Modifier les photos sélectionnées pour cette application"</string> <string name="no_unused_apps" msgid="12809387670415295">"Aucune appli inutilisée"</string> diff --git a/PermissionController/res/values-hi/strings.xml b/PermissionController/res/values-hi/strings.xml index c612e43f6..2557708bc 100644 --- a/PermissionController/res/values-hi/strings.xml +++ b/PermissionController/res/values-hi/strings.xml @@ -207,7 +207,7 @@ <string name="auto_revoke_label" msgid="5068393642936571656">"ऐप्लिकेशन का इस्तेमाल न होने पर अनुमतियां हटाएं"</string> <string name="unused_apps_label" msgid="2595428768404901064">"अनुमतियां हटाएं और जगह खाली करें"</string> <string name="unused_apps_label_v2" msgid="7058776770056517980">"इस्तेमाल न होने पर ऐप गतिविधि रोकें"</string> - <string name="unused_apps_label_v3" msgid="693340578642156657">"इस्तेमाल नहीं हुआ ऐप्लिकेशन मैनेज करें"</string> + <string name="unused_apps_label_v3" msgid="693340578642156657">"इस्तेमाल नहीं हो रहा ऐप्लिकेशन मैनेज करें"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"ऐप्लिकेशन की अनुमतियां हटाएं, डिवाइस में कुछ समय के लिए रहने वाली फ़ाइलें मिटाएं, और सूचनाएं रोकें"</string> <string name="unused_apps_summary_v2" msgid="5011313200815115802">"ऐप्लिकेशन की अनुमतियां हटाएं, डिवाइस में कुछ समय के लिए रहने वाली फ़ाइलें मिटाएं, सूचनाएं रोकें, और ऐप्लिकेशन संग्रहित करें"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"अगर इस ऐप्लिकेशन का इस्तेमाल कुछ महीनों तक नहीं किया गया, तो इसे दी गई अनुमतियां हटा दी जाएंगी. ऐसा आपके डेटा को सुरक्षित रखने के लिए किया जाएगा."</string> diff --git a/PermissionController/res/values-ky/strings.xml b/PermissionController/res/values-ky/strings.xml index ec6bde78b..f72d72a1e 100644 --- a/PermissionController/res/values-ky/strings.xml +++ b/PermissionController/res/values-ky/strings.xml @@ -209,7 +209,7 @@ <string name="unused_apps_label_v2" msgid="7058776770056517980">"Колдонулбаган колдонмолордун ишин тындыруу"</string> <string name="unused_apps_label_v3" msgid="693340578642156657">"Колдонмо колдонулбаса, аны тескеңиз"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Уруксаттар өчүрүлүп, убактылуу файлдар тазаланып, билдирмелер келбей калат"</string> - <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Уруксаттарды алып салып, убактылуу файлдарды жок кылып, билдирмелерди токтотуңуз жана колдонмону архивдеңиз"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Уруксаттарды алып салып, убактылуу файлдарды жок кылып, билдирмелерди токтотуп, колдонмону архивдейсиз"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"Эгер колдонмо бир нече ай пайдаланылбаса, жеке маалыматтарыңызды коргоо үчүн бул колдонмого берилген уруксаттар өчүрүлөт."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"Эгер колдонмо бир нече ай пайдаланылбаса, жеке дайын-даректериңизди коргоо максатында төмөнкү уруксаттар өчүрүлөт: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"Жеке дайын-даректериңизди коргоо максатында, бир нече айдан бери ачылбаган колдонмолордогу уруксаттар өчүрүлдү."</string> diff --git a/PermissionController/res/values-mr/strings.xml b/PermissionController/res/values-mr/strings.xml index 72f121d1c..c8c259d93 100644 --- a/PermissionController/res/values-mr/strings.xml +++ b/PermissionController/res/values-mr/strings.xml @@ -209,7 +209,7 @@ <string name="unused_apps_label_v2" msgid="7058776770056517980">"न वापरल्यास अॅप अॅक्टिव्हिटी थांबवा"</string> <string name="unused_apps_label_v3" msgid="693340578642156657">"वापरले नसल्यास ॲप व्यवस्थापित करा"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"परवानग्या काढून टाका, तात्पुरत्या फाइल हटवा आणि सूचना थांबवा"</string> - <string name="unused_apps_summary_v2" msgid="5011313200815115802">"परवानग्या काढून टाका, तात्पुरत्या फाइल हटवा, सूचना थांबवा आणि ॲप संग्रहित करा"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"परवानग्या काढून टाका, तात्पुरत्या फाइल हटवा, नोटिफिकेशन थांबवा आणि ॲप संग्रहित करा"</string> <string name="auto_revoke_summary" msgid="5867548789805911683">"तुमच्या डेटाचे संरक्षण करण्यासाठी, अॅप काही महिन्यांत वापरले गेले नसल्यास, या अॅपच्या परवानग्या काढल्या जातील."</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"तुमच्या डेटाचे संरक्षण करण्यासाठी, अॅप काही महिन्यांत वापरले गेले नसल्यास, पुढील परवानग्या काढल्या जातील: <xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"तुमच्या डेटाचे संरक्षण करण्यासाठी, तुम्ही काही महिन्यांत न वापरलेल्या ॲप्समधून परवानग्या काढल्या गेल्या आहेत."</string> diff --git a/PermissionController/res/values-or/strings.xml b/PermissionController/res/values-or/strings.xml index 34a2de9e7..69f4fded7 100644 --- a/PermissionController/res/values-or/strings.xml +++ b/PermissionController/res/values-or/strings.xml @@ -60,7 +60,7 @@ <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="app_permissions" msgid="3369917736607944781">"ଆପ ଅନୁମତି"</string> <string name="unused_apps" msgid="2058057455175955094">"ଅବ୍ୟବହୃତ ଆପ୍ସ"</string> <string name="edit_photos_description" msgid="5540108003480078892">"ଏହି ଆପ ପାଇଁ ଚୟନିତ ଫଟୋଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string> <string name="no_unused_apps" msgid="12809387670415295">"କୌଣସି ଅବ୍ୟବହୃତ ଆପ୍ ନାହିଁ"</string> diff --git a/PermissionController/res/values-pt-rPT/strings.xml b/PermissionController/res/values-pt-rPT/strings.xml index 590f15b2a..0ad01f7a5 100644 --- a/PermissionController/res/values-pt-rPT/strings.xml +++ b/PermissionController/res/values-pt-rPT/strings.xml @@ -210,7 +210,7 @@ <string name="unused_apps_label_v3" msgid="693340578642156657">"Gerir app se não for usada"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"Remover autorizações, eliminar ficheiros temporários e parar notificações"</string> <string name="unused_apps_summary_v2" msgid="5011313200815115802">"Remove autorizações, elimina ficheiros temporários, interrompe 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" msgid="5867548789805911683">"Para proteger os seus dados, as autorizações desta app serão removidas se a mesma não for usada 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> <string name="auto_revoke_open_app_message" msgid="8075556291711205039">"Se pretender permitir novamente as autorizações, abra a app."</string> diff --git a/PermissionController/res/values-ru/strings.xml b/PermissionController/res/values-ru/strings.xml index 36b6c8bfe..a96a76df3 100644 --- a/PermissionController/res/values-ru/strings.xml +++ b/PermissionController/res/values-ru/strings.xml @@ -580,7 +580,7 @@ <string name="security_settings" msgid="3808106921175271317">"Настройки безопасности"</string> <string name="sensor_permissions_qs" msgid="1022267900031317472">"Разрешения"</string> <string name="safety_privacy_qs_tile_title" msgid="727301867710374052">"Защита и конфиденциальность"</string> - <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Проверьте статус."</string> + <string name="safety_privacy_qs_tile_subtitle" msgid="3621544532041936749">"Проверьте состояние"</string> <string name="privacy_controls_qs" msgid="5780144882040591169">"Ваши настройки конфиденциальности"</string> <string name="security_settings_button_label_qs" msgid="8280343822465962330">"Другие настройки"</string> <string name="camera_toggle_label_qs" msgid="3880261453066157285">"Доступ к камере"</string> diff --git a/PermissionController/res/values-sr/strings.xml b/PermissionController/res/values-sr/strings.xml index 1f8085a95..95bbe7f72 100644 --- a/PermissionController/res/values-sr/strings.xml +++ b/PermissionController/res/values-sr/strings.xml @@ -474,7 +474,7 @@ <string name="permgrouprequest_location" msgid="6990232580121067883">"Желите да дозволите да апликација <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> приступа локацији овог уређаја?"</string> <string name="permgrouprequest_device_aware_location" msgid="6075412127429878638">"Дозвољавате да апликација <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> приступа локацији уређаја <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Апликација ће имати приступ локацији само док користите апликацију"</string> - <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Желите да дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> приступа локацији овог уређаја?"</string> + <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Желите да дозволите да апликација <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> приступа локацији овог уређаја?"</string> <string name="permgroupbackgroundrequest_device_aware_location" msgid="1264484517831380016">"Дозвољавате да апликација <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> приступа локацији уређаја <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgroupbackgroundrequestdetail_location" msgid="8021219324989662957">"Ова апликација можда жели да приступа локацији све време, чак и када не користите апликацију. "<annotation id="link">"Дозволите у подешавањима."</annotation></string> <string name="permgroupupgraderequest_location" msgid="8328408946822691636">"Желите ли да промените приступ локацији за апликацију <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>?"</string> diff --git a/PermissionController/res/values-uk/strings.xml b/PermissionController/res/values-uk/strings.xml index 38490365f..b05fb81e4 100644 --- a/PermissionController/res/values-uk/strings.xml +++ b/PermissionController/res/values-uk/strings.xml @@ -195,7 +195,7 @@ <string name="app_permission_button_allow_limited_access" msgid="8824410215149764113">"Дозволити обмежений доступ"</string> <string name="precise_image_description" msgid="6349638632303619872">"Точне місцезнаходження"</string> <string name="approximate_image_description" msgid="938803699637069884">"Приблизне місцезнаходження"</string> - <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Використовувати точне місцезнаходження"</string> + <string name="app_permission_location_accuracy" msgid="7166912915040018669">"Точне місцезнаходження"</string> <string name="app_permission_location_accuracy_subtitle" msgid="2654077606404987210">"Якщо вимкнено доступ до точного місцезнаходження, додатки можуть отримувати дані про приблизне"</string> <string name="app_permission_title" msgid="2090897901051370711">"Дозвіл \"<xliff:g id="PERM">%1$s</xliff:g>\""</string> <string name="app_permission_header" msgid="2951363137032603806">"<xliff:g id="PERM">%1$s</xliff:g>: доступ для цього додатка"</string> diff --git a/PermissionController/res/values-vi/strings.xml b/PermissionController/res/values-vi/strings.xml index e4d0e73e7..252b4029a 100644 --- a/PermissionController/res/values-vi/strings.xml +++ b/PermissionController/res/values-vi/strings.xml @@ -545,7 +545,7 @@ <string name="not_used_permissions_description" msgid="7595514824169388718">"Quyền mà chỉ có ứng dụng hệ thống sử dụng."</string> <string name="additional_permissions_label" msgid="7693557637462569046">"Quyền bổ sung"</string> <string name="additional_permissions_description" msgid="2186611950890732112">"Quyền do ứng dụng xác định."</string> - <string name="privdash_label_camera" msgid="1426440033626198096">"Máy ảnh"</string> + <string name="privdash_label_camera" msgid="1426440033626198096">"Camera"</string> <string name="privdash_label_microphone" msgid="8415035835803511693">"Micrô"</string> <string name="privdash_label_location" msgid="6882400763866489291">"Vị trí"</string> <string name="privdash_label_other" msgid="3710394147423236033">"Khác"</string> diff --git a/PermissionController/res/values-zh-rCN/strings.xml b/PermissionController/res/values-zh-rCN/strings.xml index 72ad13f40..ccd1d3183 100644 --- a/PermissionController/res/values-zh-rCN/strings.xml +++ b/PermissionController/res/values-zh-rCN/strings.xml @@ -209,8 +209,8 @@ <string name="unused_apps_label_v2" msgid="7058776770056517980">"暂停闲置应用的活动"</string> <string name="unused_apps_label_v3" msgid="693340578642156657">"管理闲置应用"</string> <string name="unused_apps_summary" msgid="8839466950318403115">"移除权限、删除临时文件并停止发送通知"</string> - <string name="unused_apps_summary_v2" msgid="5011313200815115802">"撤消权限、删除临时文件、停止发送通知并归档应用"</string> - <string name="auto_revoke_summary" msgid="5867548789805911683">"为了保护您的数据,如果您连续几个月未使用此应用,系统会移除它的权限。"</string> + <string name="unused_apps_summary_v2" msgid="5011313200815115802">"移除权限、删除临时文件、停止发送通知并归档应用"</string> + <string name="auto_revoke_summary" msgid="5867548789805911683">"为了保护您的数据,如果您连续几个月未使用此应用,系统会移除其权限。"</string> <string name="auto_revoke_summary_with_permissions" msgid="389712086597285013">"为了保护您的数据,如果您连续几个月未使用此应用,系统会移除其以下权限:<xliff:g id="PERMS">%1$s</xliff:g>"</string> <string name="auto_revoked_apps_page_summary" msgid="6594753657893756536">"为了保护您的数据,对于您连续几个月未使用过的应用,系统已将其权限移除。"</string> <string name="auto_revoke_open_app_message" msgid="8075556291711205039">"如果您想重新授予权限,请打开应用。"</string> diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml index 9bd675ba0..b067c41b5 100644 --- a/PermissionController/res/xml/roles.xml +++ b/PermissionController/res/xml/roles.xml @@ -1630,9 +1630,6 @@ name="android.permission.health.READ_HEART_RATE" featureFlag="android.permission.flags.Flags.replaceBodySensorPermissionEnabled" /> <permission - name="android.permission.health.READ_SKIN_TEMPERATURE" - featureFlag="android.permission.flags.Flags.platformSkinTemperatureEnabled" /> - <permission name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" featureFlag="android.permission.flags.Flags.replaceBodySensorPermissionEnabled" /> </permissions> diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java b/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java index ed21db7bb..820ff3d4e 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/Permissions.java @@ -263,7 +263,8 @@ public class Permissions { if (!wasPermissionOrAppOpGranted) { // If we've granted a permission which wasn't granted, it's no longer user set or fixed. newMask |= PackageManager.FLAG_PERMISSION_USER_FIXED - | PackageManager.FLAG_PERMISSION_USER_SET; + | PackageManager.FLAG_PERMISSION_USER_SET + | PackageManager.FLAG_PERMISSION_ONE_TIME; } // If a component gets a permission for being the default handler A and also default handler // B, we grant the weaker grant form. This only applies to default permission grant. @@ -634,7 +635,8 @@ public class Permissions { } if (!overrideUserSetAndFixed) { fixedFlags |= PackageManager.FLAG_PERMISSION_USER_FIXED - | PackageManager.FLAG_PERMISSION_USER_SET; + | PackageManager.FLAG_PERMISSION_USER_SET + | PackageManager.FLAG_PERMISSION_ONE_TIME; } return (flags & fixedFlags) != 0; } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt index b17098a13..394cb3eb7 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt @@ -233,8 +233,8 @@ private constructor( * user */ private fun isUserSet(permissionState: Map<String, PermState>): Boolean { - val flagMask = - PackageManager.FLAG_PERMISSION_USER_SET or PackageManager.FLAG_PERMISSION_USER_FIXED + val flagMask = PackageManager.FLAG_PERMISSION_USER_SET or + PackageManager.FLAG_PERMISSION_USER_FIXED or PackageManager.FLAG_PERMISSION_ONE_TIME return permissionState.any { (it.value.permFlags and flagMask) != 0 } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/BackupHelper.java b/PermissionController/src/com/android/permissioncontroller/permission/service/BackupHelper.java index 24aab174c..2fa809c6d 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/service/BackupHelper.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/service/BackupHelper.java @@ -96,6 +96,7 @@ public class BackupHelper { private static final String ATTR_USER_SET = "set"; private static final String ATTR_USER_FIXED = "fixed"; private static final String ATTR_WAS_REVIEWED = "was-reviewed"; + private static final String ATTR_ONE_TIME = "one-time"; /** Flags of permissions to <u>not</u> back up */ private static final int SYSTEM_RUNTIME_GRANT_MASK = FLAG_PERMISSION_POLICY_FIXED @@ -452,19 +453,21 @@ public class BackupHelper { private final boolean mIsUserSet; private final boolean mIsUserFixed; private final boolean mWasReviewed; + private final boolean mIsOneTime; // Not persisted, used during parsing so explicitly defined state takes precedence private final boolean mIsAddedFromSplit; private BackupPermissionState(@NonNull String permissionName, boolean isGranted, boolean isUserSet, boolean isUserFixed, boolean wasReviewed, - boolean isAddedFromSplit) { + boolean isOneTime, boolean isAddedFromSplit) { mPermissionName = permissionName; mIsGranted = isGranted; mIsUserSet = isUserSet; mIsUserFixed = isUserFixed; mWasReviewed = wasReviewed; mIsAddedFromSplit = isAddedFromSplit; + mIsOneTime = isOneTime; } /** @@ -512,6 +515,7 @@ public class BackupHelper { "true".equals(parser.getAttributeValue(null, ATTR_USER_SET)), "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED)), "true".equals(parser.getAttributeValue(null, ATTR_WAS_REVIEWED)), + "true".equals(parser.getAttributeValue(null, ATTR_ONE_TIME)), /* isAddedFromSplit */ i > 0)); } @@ -519,7 +523,8 @@ public class BackupHelper { } /** - * Is the permission granted, also considering the app-op. + * Is the permission granted, also considering the app-op. Don't consider one time grant + * as a permission grant for backup/restore. * * <p>This does not consider the review-required state of the permission. * @@ -528,7 +533,8 @@ public class BackupHelper { * @return {@code true} iff the permission and app-op is granted */ private static boolean isPermGrantedIncludingAppOp(@NonNull Permission perm) { - return perm.isGranted() && (!perm.affectsAppOp() || perm.isAppOpAllowed()); + return perm.isGranted() && (!perm.affectsAppOp() || perm.isAppOpAllowed()) + && !perm.isOneTime(); } /** @@ -549,7 +555,7 @@ public class BackupHelper { return null; } - if (!perm.isUserSet() && perm.isGrantedByDefault()) { + if (!perm.isUserSet() && !perm.isOneTime() && perm.isGrantedByDefault()) { return null; } @@ -564,10 +570,10 @@ public class BackupHelper { } if (isNotInDefaultGrantState || perm.isUserSet() || perm.isUserFixed() - || permissionWasReviewed) { + || perm.isOneTime() || permissionWasReviewed) { return new BackupPermissionState(perm.getName(), isPermGrantedIncludingAppOp(perm), perm.isUserSet(), perm.isUserFixed(), permissionWasReviewed, - /* isAddedFromSplit */ false); + perm.isOneTime(), /* isAddedFromSplit */ false); } else { return null; } @@ -628,6 +634,10 @@ public class BackupHelper { serializer.attribute(null, ATTR_WAS_REVIEWED, "true"); } + if (mIsOneTime) { + serializer.attribute(null, ATTR_ONE_TIME, "true"); + } + serializer.endTag(null, TAG_PERMISSION); } @@ -671,6 +681,10 @@ public class BackupHelper { perm.setUserSet(mIsUserSet); } + + if (!perm.isOneTime()) { + perm.setOneTime(mIsOneTime); + } } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt b/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt index 2734116dd..85145f346 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt @@ -566,10 +566,11 @@ object RuntimePermissionsUpgradeController { appPermGroup.permissions[permission.ACCESS_MEDIA_LOCATION] ?: continue if ( + !perm.isGranted && !perm.isUserSet && - !perm.isSystemFixed && - !perm.isPolicyFixed && - !perm.isGranted + !perm.isOneTime && + !perm.isSystemFixed && + !perm.isPolicyFixed ) { grants.add( Grant(false, appPermGroup, listOf(permission.ACCESS_MEDIA_LOCATION)) @@ -610,20 +611,21 @@ object RuntimePermissionsUpgradeController { // Upon upgrading to platform 33, for all targetSdk>=33 apps, do the following: // If STORAGE is granted, and the user has not set READ_MEDIA_AURAL or // READ_MEDIA_VISUAL, grant READ_MEDIA_AURAL and READ_MEDIA_VISUAL - val storageAppPermGroups = + val grantedStorageAppPermGroups = storageAndMediaAppPermGroups.filter { it.packageInfo.targetSdkVersion >= Build.VERSION_CODES.TIRAMISU && it.permGroupInfo.name == permission_group.STORAGE && it.isGranted && it.isUserSet } - for (storageAppPermGroup in storageAppPermGroups) { + for (storageAppPermGroup in grantedStorageAppPermGroups) { val pkgName = storageAppPermGroup.packageInfo.packageName val auralAppPermGroup = storageAndMediaAppPermGroups.firstOrNull { it.packageInfo.packageName == pkgName && it.permGroupInfo.name == permission_group.READ_MEDIA_AURAL && !it.isUserSet && + !it.isOneTime && !it.isUserFixed } val visualAppPermGroup = @@ -632,7 +634,8 @@ object RuntimePermissionsUpgradeController { it.permGroupInfo.name == permission_group.READ_MEDIA_VISUAL && !it.permissions .filter { it.key != permission.ACCESS_MEDIA_LOCATION } - .any { it.value.isUserSet || it.value.isUserFixed } + .any { it.value.isUserSet || it.value.isOneTime || + it.value.isUserFixed } } if (auralAppPermGroup != null) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageCustomPermissionsFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageCustomPermissionsFragment.java index 35236b8de..dd460aa2f 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageCustomPermissionsFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageCustomPermissionsFragment.java @@ -24,6 +24,8 @@ import android.view.MenuItem; import androidx.lifecycle.ViewModelProvider; +import com.android.permission.flags.Flags; +import com.android.permissioncontroller.permission.data.PermGroupsPackagesUiInfoLiveData; import com.android.permissioncontroller.permission.ui.model.ManageCustomPermissionsViewModel; import com.android.permissioncontroller.permission.ui.model.ManageCustomPermissionsViewModelFactory; @@ -48,6 +50,14 @@ public class ManageCustomPermissionsFragment extends ManagePermissionsFragment { return arguments; } + private PermGroupsPackagesUiInfoLiveData getPermGroupsLiveData() { + if (Flags.declutteredPermissionManagerEnabled()) { + return mViewModel.getAdditionaPermGroupsUiInfo(); + } else { + return mViewModel.getUiDataLiveData(); + } + } + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -56,9 +66,9 @@ public class ManageCustomPermissionsFragment extends ManagePermissionsFragment { new ManageCustomPermissionsViewModelFactory(getActivity().getApplication()); mViewModel = new ViewModelProvider(this, factory) .get(ManageCustomPermissionsViewModel.class); - mPermissionGroups = mViewModel.getUiDataLiveData().getValue(); + mPermissionGroups = getPermGroupsLiveData().getValue(); - mViewModel.getUiDataLiveData().observe(this, permissionGroups -> { + getPermGroupsLiveData().observe(this, permissionGroups -> { if (permissionGroups == null) { mPermissionGroups = new HashMap<>(); } else { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageStandardPermissionsFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageStandardPermissionsFragment.java index bf99b7134..51c0906a2 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageStandardPermissionsFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/ManageStandardPermissionsFragment.java @@ -31,7 +31,9 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.modules.utils.build.SdkLevel; +import com.android.permission.flags.Flags; import com.android.permissioncontroller.R; +import com.android.permissioncontroller.permission.data.PermGroupsPackagesUiInfoLiveData; import com.android.permissioncontroller.permission.ui.UnusedAppsFragment; import com.android.permissioncontroller.permission.ui.model.ManageStandardPermissionsViewModel; import com.android.permissioncontroller.permission.utils.StringUtils; @@ -58,6 +60,14 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr return arguments; } + private PermGroupsPackagesUiInfoLiveData getPermGroupsLiveData() { + if (Flags.declutteredPermissionManagerEnabled()) { + return mViewModel.getUsedStandardPermGroupsUiInfo(); + } else { + return mViewModel.getUiDataLiveData(); + } + } + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -65,12 +75,12 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr final Application application = getActivity().getApplication(); mViewModel = new ViewModelProvider(this, AndroidViewModelFactory.getInstance(application)) .get(ManageStandardPermissionsViewModel.class); - mPermissionGroups = mViewModel.getUiDataLiveData().getValue(); + mPermissionGroups = getPermGroupsLiveData().getValue(); - mViewModel.getUiDataLiveData().observe(this, permissionGroups -> { + getPermGroupsLiveData().observe(this, permissionGroups -> { // Once we have loaded data for the first time, further loads should be staggered, // for performance reasons. - mViewModel.getUiDataLiveData().setLoadStaggered(true); + getPermGroupsLiveData().setLoadStaggered(true); if (permissionGroups != null) { mPermissionGroups = permissionGroups; updatePermissionsUi(); @@ -80,13 +90,18 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr } // If we've loaded all LiveDatas, no need to prioritize loading any particular one - if (!mViewModel.getUiDataLiveData().isStale()) { - mViewModel.getUiDataLiveData().setFirstLoadGroup(null); + if (!getPermGroupsLiveData().isStale()) { + getPermGroupsLiveData().setFirstLoadGroup(null); } }); mViewModel.getNumCustomPermGroups().observe(this, permNames -> updatePermissionsUi()); mViewModel.getNumAutoRevoked().observe(this, show -> updatePermissionsUi()); + if (Flags.declutteredPermissionManagerEnabled()) { + mViewModel.getNumUnusedStandardPermGroups().observe( + this, show -> updatePermissionsUi() + ); + } } @Override @@ -118,6 +133,14 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr if (mViewModel.getNumCustomPermGroups().getValue() != null) { numExtraPermissions = mViewModel.getNumCustomPermGroups().getValue(); } + if (Flags.declutteredPermissionManagerEnabled()) { + if (mViewModel.getNumUnusedStandardPermGroups().getValue() != null) { + // When decluttered permission manager is enabled, unused + // permission groups will also be displayed in the additional + // permissions screen. + numExtraPermissions += mViewModel.getNumUnusedStandardPermGroups().getValue(); + } + } Preference additionalPermissionsPreference = screen.findPreference(EXTRA_PREFS_KEY); if (numExtraPermissions == 0) { @@ -198,7 +221,7 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr public void showPermissionApps(String permissionGroupName) { // If we return to this page within a reasonable time, prioritize loading data from the // permission group whose page we are going to, as that is group most likely to have changed - mViewModel.getUiDataLiveData().setFirstLoadGroup(permissionGroupName); + getPermGroupsLiveData().setFirstLoadGroup(permissionGroupName); mViewModel.showPermissionApps(this, PermissionAppsFragment.createArgs( permissionGroupName, getArguments().getLong(EXTRA_SESSION_ID))); } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageCustomPermissionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageCustomPermissionsViewModel.kt index bd80a88cd..429799157 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageCustomPermissionsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageCustomPermissionsViewModel.kt @@ -16,17 +16,23 @@ package com.android.permissioncontroller.permission.ui.model +import android.Manifest import android.app.Application +import android.content.Intent +import android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP import android.os.Bundle import androidx.fragment.app.Fragment import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.findNavController +import com.android.permission.flags.Flags import com.android.permissioncontroller.R import com.android.permissioncontroller.permission.data.PermGroupsPackagesLiveData import com.android.permissioncontroller.permission.data.PermGroupsPackagesUiInfoLiveData import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData +import com.android.permissioncontroller.permission.utils.Utils import com.android.permissioncontroller.permission.utils.navigateSafe /** @@ -38,6 +44,12 @@ import com.android.permissioncontroller.permission.utils.navigateSafe class ManageCustomPermissionsViewModel(private val app: Application) : AndroidViewModel(app) { val uiDataLiveData = PermGroupsPackagesUiInfoLiveData(app, UsedCustomPermGroupNamesLiveData()) + val additionaPermGroupsUiInfo = + PermGroupsPackagesUiInfoLiveData( + app, + if (Flags.declutteredPermissionManagerEnabled()) AdditionalPermGroupNamesLiveData(app) + else MutableLiveData<List<String>>(), + ) /** * Navigate to a Permission Apps fragment @@ -46,6 +58,15 @@ class ManageCustomPermissionsViewModel(private val app: Application) : AndroidVi * @param args The args to pass to the new fragment */ fun showPermissionApps(fragment: Fragment, args: Bundle) { + val groupName = args.getString(Intent.EXTRA_PERMISSION_GROUP_NAME) + if (groupName == Manifest.permission_group.NOTIFICATIONS) { + Utils.navigateToNotificationSettings(fragment.context!!) + return + } + if (Utils.isHealthPermissionUiEnabled() && groupName == HEALTH_PERMISSION_GROUP) { + Utils.navigateToHealthConnectSettings(fragment.context!!) + return + } fragment.findNavController().navigateSafe(R.id.manage_to_perm_apps, args) } } @@ -58,7 +79,8 @@ class ManageCustomPermissionsViewModel(private val app: Application) : AndroidVi class ManageCustomPermissionsViewModelFactory(private val app: Application) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { - @Suppress("UNCHECKED_CAST") return ManageCustomPermissionsViewModel(app) as T + @Suppress("UNCHECKED_CAST") + return ManageCustomPermissionsViewModel(app) as T } } @@ -77,3 +99,32 @@ class UsedCustomPermGroupNamesLiveData : SmartUpdateMediatorLiveData<List<String /* No op override */ } } + +/** + * A LiveData that is the union of LiveData UsedCustomPermGroupNamesLiveData and + * UnusedStandardPermGroupNamesLiveData. + * + * @param app The current application of the fragment + */ +class AdditionalPermGroupNamesLiveData(private val app: Application) : + SmartUpdateMediatorLiveData<List<String>>() { + + val usedCustomGroupNames = UsedCustomPermGroupNamesLiveData() + val unusedStandardGroupNames = UnusedStandardPermGroupNamesLiveData(app) + + init { + addSource(usedCustomGroupNames) { update() } + addSource(unusedStandardGroupNames) { update() } + } + + private fun combineGroupNames( + groupNames1: List<String>?, + groupNames2: List<String>?, + ): List<String> { + return (groupNames1 ?: emptyList()) + (groupNames2 ?: emptyList()) + } + + override fun onUpdate() { + value = combineGroupNames(usedCustomGroupNames.value, unusedStandardGroupNames.value) + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt index aeab0aa89..f94999626 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt @@ -23,8 +23,11 @@ import android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP import android.os.Bundle import androidx.fragment.app.Fragment import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MediatorLiveData +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.map import androidx.navigation.fragment.findNavController +import com.android.permission.flags.Flags import com.android.permissioncontroller.R import com.android.permissioncontroller.permission.data.PermGroupsPackagesLiveData import com.android.permissioncontroller.permission.data.PermGroupsPackagesUiInfoLiveData @@ -45,7 +48,21 @@ import com.android.permissioncontroller.permission.utils.navigateSafe class ManageStandardPermissionsViewModel(private val app: Application) : AndroidViewModel(app) { val uiDataLiveData = PermGroupsPackagesUiInfoLiveData(app, StandardPermGroupNamesLiveData) + val usedStandardPermGroupsUiInfo = + PermGroupsPackagesUiInfoLiveData( + app, + if (Flags.declutteredPermissionManagerEnabled()) UsedStandardPermGroupNamesLiveData(app) + else MutableLiveData<List<String>>(), + ) val numCustomPermGroups = NumCustomPermGroupsWithPackagesLiveData() + val numUnusedStandardPermGroups = + MediatorLiveData<Int>().apply { + if (Flags.declutteredPermissionManagerEnabled()) { + addSource(UnusedStandardPermGroupNamesLiveData(app)) { groupNames -> + value = groupNames.size + } + } + } val numAutoRevoked = unusedAutoRevokePackagesLiveData.map { it?.size ?: 0 } /** @@ -98,3 +115,55 @@ class NumCustomPermGroupsWithPackagesLiveData() : SmartUpdateMediatorLiveData<In value = customPermGroupPackages.value?.size ?: 0 } } + +/** + * A LiveData that tracks the names of the platform-defined permission groups, such that at least + * one of the permissions in the group has been requested at runtime by at least one non-system + * application or has been pregranted to a non-system application. + * + * @param app The current application of the fragment + */ +class UsedStandardPermGroupNamesLiveData(private val app: Application) : + SmartUpdateMediatorLiveData<List<String>>() { + init { + addSource(PermGroupsPackagesUiInfoLiveData(app, StandardPermGroupNamesLiveData)) { + permGroups -> + if (permGroups.values.any { it != null }) { + value = + permGroups + .filterValues { it != null && it.nonSystemUserSetOrPreGranted > 0 } + .keys + .toList() + } + } + } + + override fun onUpdate() { + /* No op override */ + } +} + +/** + * A LiveData that tracks the names of the platform-defined permission groups, such that none of the + * the permissions in the group has been requested at runtime by any non-system application nor has + * been pregranted to any non-system application. + * + * @param app The current application of the fragment + */ +class UnusedStandardPermGroupNamesLiveData(private val app: Application) : + SmartUpdateMediatorLiveData<List<String>>() { + init { + addSource(PermGroupsPackagesUiInfoLiveData(app, StandardPermGroupNamesLiveData)) { + permGroups -> + value = + permGroups + .filterValues { it != null && it.nonSystemUserSetOrPreGranted == 0 } + .keys + .toList() + } + } + + override fun onUpdate() { + /* No op override */ + } +} 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 078eefe3b..2933d6fda 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt @@ -19,6 +19,7 @@ package com.android.permissioncontroller.permission.ui.wear import android.content.Context import android.content.pm.PackageManager import android.content.pm.PermissionInfo +import android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP import android.os.Build import android.os.UserHandle import android.util.ArraySet @@ -319,6 +320,10 @@ class WearAppPermissionGroupsHelper( ) { // Redirect to location controller extra package settings. LocationUtils.startLocationControllerExtraPackageSettings(context, user) + } else if (permGroupName.equals(HEALTH_PERMISSION_GROUP) + && android.permission.flags.Flags.replaceBodySensorPermissionEnabled()) { + // Redirect to Health&Fitness UI + Utils.navigateToAppHealthConnectSettings(fragment.requireContext(), packageName, user) } else { val args = WearAppPermissionFragment.createArgs( diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt index 3198a4c09..a3446f802 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt @@ -139,6 +139,12 @@ object PermissionMapping { PLATFORM_PERMISSIONS[Manifest.permission.NEARBY_WIFI_DEVICES] = Manifest.permission_group.NEARBY_DEVICES } + // Ranging permission will be supported from Android B+, update this when isAtLeastB() + // is available. + if (SdkLevel.isAtLeastV() && Flags.rangingPermissionEnabled()) { + PLATFORM_PERMISSIONS[Manifest.permission.RANGING] = + Manifest.permission_group.NEARBY_DEVICES + } // Any updates to the permissions for the CALL_LOG permission group must also be made in // Permissions {@link com.android.role.controller.model.Permissions} in the role diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/hibernation/HibernationPolicyTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/hibernation/HibernationPolicyTest.kt index eeea96c5d..15a37532f 100644 --- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/hibernation/HibernationPolicyTest.kt +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/hibernation/HibernationPolicyTest.kt @@ -186,7 +186,6 @@ class HibernationPolicyTest { } @Test - @Ignore("b/373082442") fun onReceive_shouldInitializeAndAdjustStartTimeOfUnusedAppTracking() { receiver.onReceive(context, Intent(Intent.ACTION_BOOT_COMPLETED)) val startTimeOfUnusedAppTracking = @@ -230,6 +229,11 @@ class HibernationPolicyTest { } @Test + @Ignore("b/371061181") + // This method under test initializes several SmartAsyncMediatorLiveData classes which run code + // on GlobalScope which the unit test has no control over. This can lead to the code running + // during other tests which may not have the right static mocks. + // Until this is fixed, this test should be ignored to prevent flaky test faliures. fun isPackageExemptBySystem_isCallingApp_returnsTrue() = runBlocking<Unit> { val pkgInfo = makePackageInfo(TEST_PKG_NAME) diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageCustomPermissionsFragmentTest.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageCustomPermissionsFragmentTest.kt index eb7be564b..b38f5f40a 100644 --- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageCustomPermissionsFragmentTest.kt +++ b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageCustomPermissionsFragmentTest.kt @@ -26,10 +26,12 @@ import androidx.test.uiautomator.By import com.android.compatibility.common.util.SystemUtil.eventually import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObject +import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObjectOrNull import com.android.permissioncontroller.permissionui.getUsageCountsFromUi import com.android.permissioncontroller.permissionui.wakeUpScreen import com.google.common.truth.Truth.assertThat import org.junit.After +import org.junit.Assert.assertNotNull import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -47,6 +49,7 @@ class ManageCustomPermissionsFragmentTest : BaseHandheldPermissionUiTest() { private val PERM_LABEL = "Permission A" private val PERM = "com.android.permissioncontroller.tests.A" private val ADDITIONAL_PERMISSIONS_LABEL = "Additional permissions" + private val BODY_SENSORS_LABEL = "Body sensors" @Before fun setup() { @@ -92,6 +95,14 @@ class ManageCustomPermissionsFragmentTest : BaseHandheldPermissionUiTest() { eventually { assertThat(getUsageCountsFromUi(PERM_LABEL)).isEqualTo(original) } } + @Test + fun bodySensorsEitherDisplayedInMainPageOrInAdditional() { + if (waitFindObjectOrNull(By.textContains(BODY_SENSORS_LABEL)) == null) { + waitFindObject(By.textContains(ADDITIONAL_PERMISSIONS_LABEL)).click() + assertNotNull(waitFindObjectOrNull(By.textContains(BODY_SENSORS_LABEL))) + } + } + @After fun tearDown() { uninstallApp(DEFINER_PKG) diff --git a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageStandardPermissionsFragmentTest.kt b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageStandardPermissionsFragmentTest.kt index 1ad876245..fcce09450 100644 --- a/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageStandardPermissionsFragmentTest.kt +++ b/PermissionController/tests/permissionui/src/com/android/permissioncontroller/permissionui/ui/handheld/ManageStandardPermissionsFragmentTest.kt @@ -23,6 +23,8 @@ import android.permission.cts.PermissionUtils.grantPermission import android.permission.cts.PermissionUtils.install import android.permission.cts.PermissionUtils.revokePermission import android.permission.cts.PermissionUtils.uninstallApp +import android.platform.test.annotations.RequiresFlagsEnabled +import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.util.Log import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.uiautomator.By @@ -30,17 +32,23 @@ import com.android.compatibility.common.util.SystemUtil.eventually import com.android.compatibility.common.util.SystemUtil.getEventually import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObjectOrNull +import com.android.permission.flags.Flags import com.android.permissioncontroller.permissionui.getUsageCountsFromUi import com.android.permissioncontroller.permissionui.wakeUpScreen import com.google.common.truth.Truth.assertThat import org.junit.After +import org.junit.Assert.assertNull import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith /** Simple tests for {@link ManageStandardPermissionsFragment} */ @RunWith(AndroidJUnit4::class) class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { + + @JvmField @Rule val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() + @Before fun setup() { wakeUpScreen() @@ -117,7 +125,7 @@ class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { assertThat(afterInstall.granted).isEqualTo(original.granted) assertThat(afterInstall.total).isEqualTo(original.total + 1) }, - TIMEOUT + TIMEOUT, ) } @@ -127,13 +135,13 @@ class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { install(LOCATION_USER_APK) eventually( { assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL)).isNotEqualTo(original) }, - TIMEOUT + TIMEOUT, ) uninstallApp(LOCATION_USER_PKG) eventually( { assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL)).isEqualTo(original) }, - TIMEOUT + TIMEOUT, ) } @@ -147,7 +155,7 @@ class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL).total) .isEqualTo(original.total + 1) }, - TIMEOUT + TIMEOUT, ) grantPermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION) @@ -170,7 +178,7 @@ class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL).granted) .isNotEqualTo(original.granted) }, - TIMEOUT + TIMEOUT, ) revokePermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION) @@ -190,7 +198,7 @@ class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { { assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore + 1) }, - TIMEOUT + TIMEOUT, ) } @@ -202,13 +210,13 @@ class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { install(ADDITIONAL_USER_APK) eventually( { assertThat(getAdditionalPermissionCount()).isNotEqualTo(additionalPermissionBefore) }, - TIMEOUT + TIMEOUT, ) uninstallApp(ADDITIONAL_USER_PKG) eventually( { assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore) }, - TIMEOUT + TIMEOUT, ) } @@ -220,16 +228,23 @@ class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() { install(ADDITIONAL_USER_APK) eventually( { assertThat(getAdditionalPermissionCount()).isNotEqualTo(additionalPermissionBefore) }, - TIMEOUT + TIMEOUT, ) uninstallApp(ADDITIONAL_DEFINER_PKG) eventually( { assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore) }, - TIMEOUT + TIMEOUT, ) } + @Test + @RequiresFlagsEnabled(Flags.FLAG_DECLUTTERED_PERMISSION_MANAGER_ENABLED) + fun noUnusedPermissionGroupDisplayedInTheMainPage() { + eventually { assertNull(waitFindObjectOrNull(By.hasChild(By.textStartsWith("0 of 0")))) } + eventually { assertNull(waitFindObjectOrNull(By.hasChild(By.textStartsWith("0/0")))) } + } + companion object { private val LOG_TAG = ManageStandardPermissionsFragmentTest::class.java.simpleName diff --git a/SafetyCenter/Resources/res/values-or-v35/strings.xml b/SafetyCenter/Resources/res/values-or-v35/strings.xml index 5023efd4d..4a0ba87a5 100644 --- a/SafetyCenter/Resources/res/values-or-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-or-v35/strings.xml @@ -21,7 +21,7 @@ <string name="cellular_network_security_summary" msgid="7319307247487475572">"ନେଟୱାର୍କ ପ୍ରକାର, ଏନକ୍ରିପସନ, ବିଜ୍ଞପ୍ତି ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="privacy_title" msgid="7047524783080782769">"ଗୋପନୀୟତା"</string> - <string name="privacy_sources_title" msgid="309304028326660956">"ଗୋପନୀୟତା ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> + <string name="privacy_sources_title" msgid="309304028326660956">"ଗୋପନୀୟତା ନିୟନ୍ତ୍ରଣ"</string> <string name="privacy_sources_summary" msgid="2165270848857537278">"ଅନୁମତି, ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> <string name="privacy_additional_title" msgid="4239060639056083649"></string> <string name="private_space_title" msgid="6158245041481535879">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string> diff --git a/SafetyCenter/Resources/res/values-sv-v35/strings.xml b/SafetyCenter/Resources/res/values-sv-v35/strings.xml index 77a6de01f..d1f44114e 100644 --- a/SafetyCenter/Resources/res/values-sv-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-sv-v35/strings.xml @@ -22,7 +22,7 @@ <string name="biometrics_title_for_private_profile" msgid="542819107383037820"></string> <string name="privacy_title" msgid="7047524783080782769">"Integritet"</string> <string name="privacy_sources_title" msgid="309304028326660956">"Integritetsinställningar"</string> - <string name="privacy_sources_summary" msgid="2165270848857537278">"Behörigheter, inställningar"</string> + <string name="privacy_sources_summary" msgid="2165270848857537278">"Behörigheter och inställningar"</string> <string name="privacy_additional_title" msgid="4239060639056083649"></string> <string name="private_space_title" msgid="6158245041481535879">"Privat rum"</string> <string name="private_space_summary" msgid="529869826714610294">"Ställ in privat rum med mera"</string> diff --git a/flags/flags.aconfig b/flags/flags.aconfig index 5f3e84121..4cb084988 100644 --- a/flags/flags.aconfig +++ b/flags/flags.aconfig @@ -104,7 +104,7 @@ flag { name: "app_permission_fragment_uses_preferences" is_exported: true namespace: "permissions" - description: "This flag enables AppPermissionFragment rather than LegacyAppPermissionFragment (to support BC25)" + description: "This flag enables AppPermissionFragment rather than LegacyAppPermissionFragment" bug: "349675008" is_fixed_read_only: true } @@ -131,7 +131,7 @@ flag { name: "wear_compose_material3" is_exported: true namespace: "permissions" - description: "This flag enables material3 design system for wear ui components (to support BC25)" + description: "This flag enables material3 design system for wear ui components" bug: "370489422" is_fixed_read_only: true } @@ -144,3 +144,12 @@ flag { bug: "365823624" is_fixed_read_only: true } + +flag { + name: "expressive_design_enabled" + is_exported: true + namespace: "permissions" + description: "This flag is used to enable Expressive Design for Settings pages inside PermissionController" + bug: "375480184" + is_fixed_read_only: true +}
\ No newline at end of file diff --git a/service/java/com/android/permission/util/UserUtils.java b/service/java/com/android/permission/util/UserUtils.java index 33389a88f..639c7aacb 100644 --- a/service/java/com/android/permission/util/UserUtils.java +++ b/service/java/com/android/permission/util/UserUtils.java @@ -19,6 +19,7 @@ package com.android.permission.util; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.Context; +import android.content.pm.PackageManager; import android.os.Binder; import android.os.Process; import android.os.UserHandle; @@ -30,6 +31,7 @@ import com.android.permission.compat.UserHandleCompat; import com.android.permission.flags.Flags; import java.util.List; +import java.util.Objects; /** Utility class to deal with Android users. */ public final class UserUtils { @@ -81,6 +83,32 @@ public final class UserUtils { } } + /** Returns all the enabled user profiles on the device. */ + @NonNull + public static List<UserHandle> getUserProfiles(@NonNull Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + // This call requires the QUERY_USERS permission. + final long identity = Binder.clearCallingIdentity(); + try { + return userManager.getUserProfiles(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + /** Returns the parent of a given user. */ + public static UserHandle getProfileParent(@UserIdInt int userId, @NonNull Context context) { + Context userContext = getUserContext(userId, context); + UserManager userManager = userContext.getSystemService(UserManager.class); + // This call requires the INTERACT_ACROSS_USERS permission. + final long identity = Binder.clearCallingIdentity(); + try { + return userManager.getProfileParent(UserHandle.of(userId)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + /** Returns whether a given {@code userId} corresponds to a managed profile. */ public static boolean isManagedProfile(@UserIdInt int userId, @NonNull Context context) { UserManager userManager = context.getSystemService(UserManager.class); @@ -107,8 +135,7 @@ public final class UserUtils { // MANAGE_USERS, QUERY_USERS, or INTERACT_ACROSS_USERS. final long identity = Binder.clearCallingIdentity(); try { - Context userContext = context - .createContextAsUser(UserHandle.of(userId), /* flags= */ 0); + Context userContext = getUserContext(userId, context); UserManager userManager = userContext.getSystemService(UserManager.class); return userManager != null && userManager.isPrivateProfile(); } finally { @@ -141,4 +168,13 @@ public final class UserUtils { Binder.restoreCallingIdentity(identity); } } + + @NonNull + public static Context getUserContext(@UserIdInt int userId, @NonNull Context context) { + if (SdkLevel.isAtLeastS() && context.getUser().getIdentifier() == userId) { + return context; + } else { + return context.createContextAsUser(UserHandle.of(userId), 0); + } + } } diff --git a/service/java/com/android/safetycenter/UserProfileGroup.java b/service/java/com/android/safetycenter/UserProfileGroup.java index 46a440bf7..3202c3776 100644 --- a/service/java/com/android/safetycenter/UserProfileGroup.java +++ b/service/java/com/android/safetycenter/UserProfileGroup.java @@ -134,9 +134,9 @@ public final class UserProfileGroup { * is disabled. */ public static UserProfileGroup fromUser(Context context, @UserIdInt int userId) { - UserManager userManager = getUserManagerForUser(userId, context); - List<UserHandle> userProfiles = getEnabledUserProfiles(userManager); - UserHandle profileParent = getProfileParent(userManager, userId); + Context userContext = UserUtils.getUserContext(userId, context); + List<UserHandle> userProfiles = UserUtils.getUserProfiles(userContext); + UserHandle profileParent = UserUtils.getProfileParent(userId, userContext); int profileParentUserId = userId; if (profileParent != null) { profileParentUserId = profileParent.getIdentifier(); @@ -192,23 +192,10 @@ public final class UserProfileGroup { } private static UserManager getUserManagerForUser(@UserIdInt int userId, Context context) { - Context userContext = getUserContext(context, UserHandle.of(userId)); + Context userContext = UserUtils.getUserContext(userId, context); return requireNonNull(userContext.getSystemService(UserManager.class)); } - private static Context getUserContext(Context context, UserHandle userHandle) { - if (Process.myUserHandle().equals(userHandle)) { - return context; - } else { - try { - return context.createPackageContextAsUser( - context.getPackageName(), /* flags= */ 0, userHandle); - } catch (PackageManager.NameNotFoundException doesNotHappen) { - throw new IllegalStateException(doesNotHappen); - } - } - } - private static boolean isProfile(@UserIdInt int userId, Context context) { // This call requires the INTERACT_ACROSS_USERS permission. final long callingId = Binder.clearCallingIdentity(); @@ -220,27 +207,6 @@ public final class UserProfileGroup { } } - private static List<UserHandle> getEnabledUserProfiles(UserManager userManager) { - // This call requires the QUERY_USERS permission. - final long callingId = Binder.clearCallingIdentity(); - try { - return userManager.getUserProfiles(); - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - - @Nullable - private static UserHandle getProfileParent(UserManager userManager, @UserIdInt int userId) { - // This call requires the INTERACT_ACROSS_USERS permission. - final long callingId = Binder.clearCallingIdentity(); - try { - return userManager.getProfileParent(UserHandle.of(userId)); - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - /** Returns the profile parent user id of the {@link UserProfileGroup}. */ public int getProfileParentUserId() { return mProfileParentUserId; diff --git a/tests/cts/permission/src/android/permission/cts/OneTimePermissionTest.java b/tests/cts/permission/src/android/permission/cts/OneTimePermissionTest.java index 2692c6e7c..291633aab 100644 --- a/tests/cts/permission/src/android/permission/cts/OneTimePermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/OneTimePermissionTest.java @@ -290,34 +290,18 @@ public class OneTimePermissionTest { } private void exitApp() { - boolean[] hasExited = {false}; - try { - new Thread(() -> { - while (!hasExited[0]) { - DreamManager mDreamManager = mContext.getSystemService(DreamManager.class); - mUiDevice.pressBack(); - runWithShellPermissionIdentity(() -> { - if (mDreamManager.isDreaming()) { - mDreamManager.stopDream(); - } - }); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - } + eventually(() -> { + mUiDevice.pressBack(); + runWithShellPermissionIdentity(() -> { + DreamManager mDreamManager = mContext.getSystemService(DreamManager.class); + if (mDreamManager.isDreaming()) { + mDreamManager.stopDream(); } - }).start(); - eventually(() -> { - runWithShellPermissionIdentity(() -> { - if (mActivityManager.getPackageImportance(APP_PKG_NAME) - <= IMPORTANCE_FOREGROUND) { - throw new AssertionError("Unable to exit application"); - } - }); + Assert.assertFalse("Unable to exit application", + mActivityManager.getPackageImportance(APP_PKG_NAME) + <= IMPORTANCE_FOREGROUND); }); - } finally { - hasExited[0] = true; - } + }); } private void clickOneTimeButton() throws Throwable { diff --git a/tests/cts/permissionpolicy/Android.bp b/tests/cts/permissionpolicy/Android.bp index e6041eea2..07fde8bff 100644 --- a/tests/cts/permissionpolicy/Android.bp +++ b/tests/cts/permissionpolicy/Android.bp @@ -37,6 +37,8 @@ android_test { "permission-test-util-lib", "androidx.test.rules", "flag-junit", + "android.app.flags-aconfig", + "android.permission.flags-aconfig-java-export", ], srcs: [ "src/**/*.java", diff --git a/tests/cts/permissionpolicy/res/raw/android_manifest.xml b/tests/cts/permissionpolicy/res/raw/android_manifest.xml index 2eff8b0af..d30931c3f 100644 --- a/tests/cts/permissionpolicy/res/raw/android_manifest.xml +++ b/tests/cts/permissionpolicy/res/raw/android_manifest.xml @@ -2396,6 +2396,16 @@ android:label="@string/permlab_nearby_wifi_devices" android:protectionLevel="dangerous" /> + <!-- Required to be able to range to devices using any ranging technology. + @FlaggedApi("android.permission.flags.ranging_permission_enabled") + <p>Protection level: dangerous --> + <permission android:name="android.permission.RANGING" + android:permissionGroup="android.permission-group.UNDEFINED" + android:description="@string/permdesc_ranging" + android:label="@string/permlab_ranging" + android:protectionLevel="dangerous" + android:featureFlag="android.permission.flags.ranging_permission_enabled" /> + <!-- @SystemApi @TestApi Allows an application to suspend other apps, which will prevent the user from using them until they are unsuspended. @hide @@ -2606,12 +2616,22 @@ <!-- @SystemApi Allows access to perform vendor effects in the vibrator. <p>Protection level: signature + @FlaggedApi("android.os.vibrator.vendor_vibration_effects") @hide --> <permission android:name="android.permission.VIBRATE_VENDOR_EFFECTS" android:protectionLevel="signature|privileged" android:featureFlag="android.os.vibrator.vendor_vibration_effects" /> + <!-- @SystemApi Allows access to start a vendor vibration session. + <p>Protection level: signature + @FlaggedApi("android.os.vibrator.vendor_vibration_effects") + @hide + --> + <permission android:name="android.permission.START_VIBRATION_SESSIONS" + android:protectionLevel="signature|privileged" + android:featureFlag="android.os.vibrator.vendor_vibration_effects" /> + <!-- @SystemApi Allows access to the vibrator state. <p>Protection level: signature @hide @@ -4248,6 +4268,18 @@ android:description="@string/permdesc_hideOverlayWindows" android:protectionLevel="normal" /> + <!-- Allows an app to enter Picture-in-Picture mode when the user is not explicitly requesting + it. This includes using {@link PictureInPictureParams.Builder#setAutoEnterEnabled} as well + as lifecycle methods such as {@link Activity#onUserLeaveHint} and {@link Activity#onPause} + to enter PiP when the user leaves the app. + This permission should only be used for certain PiP + <a href="{@docRoot}training/tv/get-started/multitasking#usage-types">usage types</a>. + @FlaggedApi("android.app.enable_tv_implicit_enter_pip_restriction") + --> + <permission android:name="android.permission.TV_IMPLICIT_ENTER_PIP" + android:protectionLevel="normal" + android:featureFlag="android.app.enable_tv_implicit_enter_pip_restriction" /> + <!-- ================================== --> <!-- Permissions affecting the system wallpaper --> <!-- ================================== --> @@ -4754,6 +4786,27 @@ <permission android:name="android.permission.PROVIDE_REMOTE_CREDENTIALS" android:protectionLevel="signature|privileged|role" /> + <!-- @FlaggedApi(com.android.settingslib.flags.Flags.FLAG_SETTINGS_CATALYST) + Allows an application to access the Settings Preference services to read settings exposed + by the system Settings app and system apps that contribute settings surfaced by the + Settings app. + <p>This allows the calling application to read settings values through the host + application, agnostic of underlying storage. --> + <permission android:name="android.permission.READ_SYSTEM_PREFERENCES" + android:protectionLevel="signature|privileged|role" + android:featureFlag="com.android.settingslib.flags.settings_catalyst" /> + + <!-- @FlaggedApi(com.android.settingslib.flags.Flags.FLAG_SETTINGS_CATALYST) + Allows an application to access the Settings Preference services to write settings + values exposed by the system Settings app and system apps that contribute settings surfaced + in the Settings app. + <p>This allows the calling application to write settings values + through the host application, agnostic of underlying storage. + <p>Protection Level: signature|privileged|appop - appop to be added in followup --> + <permission android:name="android.permission.WRITE_SYSTEM_PREFERENCES" + android:protectionLevel="signature|privileged" + android:featureFlag="com.android.settingslib.flags.settings_catalyst" /> + <!-- ========================================= --> <!-- Permissions for special development tools --> <!-- ========================================= --> @@ -8301,6 +8354,28 @@ android:protectionLevel="internal" android:featureFlag="android.content.pm.verification_service" /> + <!-- + @SystemApi + @FlaggedApi("android.media.tv.flags.media_quality_fw") + Allows an application to access its picture profile from the media quality database. + <p> Protection level: signature|privileged|vendor privileged + @hide + --> + <permission android:name="android.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE" + android:protectionLevel="signature|privileged|vendorPrivileged" + android:featureFlag="android.media.tv.flags.media_quality_fw"/> + + <!-- + @SystemApi + @FlaggedApi("android.media.tv.flags.media_quality_fw") + Allows an application to access its sound profile from the media quality database. + <p> Protection level: signature|privileged|vendor privileged + @hide + --> + <permission android:name="android.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE" + android:protectionLevel="signature|privileged|vendorPrivileged" + android:featureFlag="android.media.tv.flags.media_quality_fw"/> + <!-- Allows app to enter trade-in-mode. <p>Protection level: signature|privileged @hide @@ -8309,6 +8384,34 @@ android:protectionLevel="signature|privileged" android:featureFlag="com.android.tradeinmode.flags.enable_trade_in_mode" /> + <!-- @SystemApi + @FlaggedApi("android.media.tv.flags.kids_mode_tvdb_sharing") + This permission is required when accessing information related to + singleUser-ed TIS session. + <p>This should only be used by OEM. + <p>Protection level: signature|privileged|vendorPrivileged + @hide + --> + <permission android:name="android.permission.SINGLE_USER_TIS_ACCESS" + android:protectionLevel="signature|privileged|vendorPrivileged" + android:featureFlag="android.media.tv.flags.kids_mode_tvdb_sharing"/> + + <!-- + This permission allows the system to receive PACKAGE_CHANGED broadcasts when the component + state of a non-exported component has been changed. + <p>Not for use by third-party applications. </p> + <p>Protection level: internal + @hide + --> + <permission + android:name="android.permission.INTERNAL_RECEIVE_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED" + android:protectionLevel="internal" + android:featureFlag="android.content.pm.reduce_broadcasts_for_component_state_changes"/> + + <uses-permission + android:name="android.permission.INTERNAL_RECEIVE_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED" + android:featureFlag="android.content.pm.reduce_broadcasts_for_component_state_changes"/> + <!-- Attribution for Geofencing service. --> <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/> <!-- Attribution for Country Detector. --> diff --git a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/RuntimePermissionProperties.kt b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/RuntimePermissionProperties.kt index 6b3ae5f2e..70832b6ba 100644 --- a/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/RuntimePermissionProperties.kt +++ b/tests/cts/permissionpolicy/src/android/permissionpolicy/cts/RuntimePermissionProperties.kt @@ -33,6 +33,7 @@ import android.Manifest.permission.NEARBY_WIFI_DEVICES import android.Manifest.permission.PACKAGE_USAGE_STATS import android.Manifest.permission.POST_NOTIFICATIONS import android.Manifest.permission.PROCESS_OUTGOING_CALLS +import android.Manifest.permission.RANGING import android.Manifest.permission.READ_CALENDAR import android.Manifest.permission.READ_CALL_LOG import android.Manifest.permission.READ_CELL_BROADCASTS @@ -59,6 +60,7 @@ import android.content.pm.PackageManager.GET_PERMISSIONS import android.content.pm.PermissionInfo.PROTECTION_DANGEROUS import android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP import android.os.Build +import android.permission.flags.Flags import android.permission.PermissionManager import androidx.test.platform.app.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 @@ -187,6 +189,12 @@ class RuntimePermissionProperties { // runtime permission expectedPerms.add(READ_MEDIA_VISUAL_USER_SELECTED) + // Add runtime permissions added in B which were _not_ split from a previously existing + // runtime permission + if (Flags.rangingPermissionEnabled()) { + expectedPerms.add(RANGING) + } + assertThat(expectedPerms).containsExactlyElementsIn(platformRuntimePerms.map { it.name }) } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt index e3197599c..19b67e729 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/CameraMicIndicatorsPermissionTest.kt @@ -28,6 +28,7 @@ import android.os.Build import android.os.Process import android.os.SystemClock import android.os.SystemProperties +import android.os.UserManager import android.permission.PermissionManager import android.permission.cts.MtsIgnore import android.platform.test.annotations.AsbSecurityTest @@ -161,6 +162,8 @@ class CameraMicIndicatorsPermissionTest : StsExtraBusinessLogicTestCase { @Before fun setUp() { + // Camera and Mic are not supported for secondary user visible as a background user. + assumeFalse(isAutomotiveWithVisibleBackgroundUser()) runWithShellPermissionIdentity { screenTimeoutBeforeTest = Settings.System.getLong(context.contentResolver, Settings.System.SCREEN_OFF_TIMEOUT) @@ -209,6 +212,9 @@ class CameraMicIndicatorsPermissionTest : StsExtraBusinessLogicTestCase { @After fun tearDown() { + if (isAutomotiveWithVisibleBackgroundUser()) { + return + } uninstall() if (isCar) { // Deselect the indicator since it persists otherwise @@ -775,4 +781,10 @@ class CameraMicIndicatorsPermissionTest : StsExtraBusinessLogicTestCase { private fun byOneOfText(vararg textValues: String) = By.text(Pattern.compile(textValues.joinToString(separator = "|") { Pattern.quote(it) })) + + fun isAutomotiveWithVisibleBackgroundUser(): Boolean { + val userManager = context.getSystemService(UserManager::class.java) + return packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) && + userManager.isVisibleBackgroundUsersSupported() + } } |