diff options
121 files changed, 897 insertions, 914 deletions
diff --git a/PermissionController/res/values-af/strings.xml b/PermissionController/res/values-af/strings.xml index a32781960..fdbf4be1b 100644 --- a/PermissionController/res/values-af/strings.xml +++ b/PermissionController/res/values-af/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Oopmaak van skakels"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Verstek vir werk"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Verstek vir privaat ruimte"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Geoptimeer vir toestel"</string> + <string name="default_app_others" msgid="7793029848126079876">"Ander"</string> <string name="default_app_none" msgid="9084592086808194457">"Geen"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Stelselverstek)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Geen apps nie"</string> diff --git a/PermissionController/res/values-am/strings.xml b/PermissionController/res/values-am/strings.xml index e4942b907..8b4cffe19 100644 --- a/PermissionController/res/values-am/strings.xml +++ b/PermissionController/res/values-am/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"አገናኞችን በመክፈት ላይ"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"ለሥራ ነባሪ"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ለግል ቦታ ነባሪ"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ለመሣሪያ የተባ"</string> + <string name="default_app_others" msgid="7793029848126079876">"ሌሎች"</string> <string name="default_app_none" msgid="9084592086808194457">"ምንም"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(የሥርዓት ነባሪ)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"መተግበሪያዎች የሉም"</string> diff --git a/PermissionController/res/values-ar/strings.xml b/PermissionController/res/values-ar/strings.xml index 3f3c9577c..e22ec0182 100644 --- a/PermissionController/res/values-ar/strings.xml +++ b/PermissionController/res/values-ar/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"فتح الروابط"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"التطبيقات التلقائية للعمل"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"التطبيقات التلقائية في المساحة الخاصّة"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"متوافقة مع الجهاز"</string> + <string name="default_app_others" msgid="7793029848126079876">"غير ذلك"</string> <string name="default_app_none" msgid="9084592086808194457">"غير محدَّد"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(الإعداد التلقائي للنظام)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"ليست هناك تطبيقات."</string> @@ -477,7 +475,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> @@ -497,7 +495,7 @@ <string name="permgrouprequest_coarselocation_imagetext" msgid="8650605041483025297">"تقريبي"</string> <string name="permgrouprequest_calendar" msgid="1493150855673603806">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى التقويم؟"</string> <string name="permgrouprequest_device_aware_calendar" msgid="7161929851377463612">"هل تريد السماح لـ <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_sms" msgid="5672063688745420991">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بإرسال رسائل SMS وعرضها؟"</string> + <string name="permgrouprequest_sms" msgid="5672063688745420991">"هل مطلوب السماح لتطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> بإرسال رسائل SMS وعرضها؟"</string> <string name="permgrouprequest_device_aware_sms" msgid="6639977653040502291">"هل تريد السماح لـ <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_storage" msgid="8717773092518621602">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى الصور والوسائط والملفات على جهازك؟"</string> <string name="permgrouprequest_device_aware_storage" msgid="6933251810928606636">"هل تريد السماح لـ <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-az/strings.xml b/PermissionController/res/values-az/strings.xml index 76d4a10c1..14d93b2aa 100644 --- a/PermissionController/res/values-az/strings.xml +++ b/PermissionController/res/values-az/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Linklərin açılması"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"İş üçün defolt"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Şəxsi sahə üçün defolt"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Cihaz üçün optimallaşdırılıb"</string> + <string name="default_app_others" msgid="7793029848126079876">"Digərləri"</string> <string name="default_app_none" msgid="9084592086808194457">"Yoxdur"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Sistem defoltu)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Tətbiq yoxdur"</string> diff --git a/PermissionController/res/values-be/strings.xml b/PermissionController/res/values-be/strings.xml index 37c0a94c3..26ea7e101 100644 --- a/PermissionController/res/values-be/strings.xml +++ b/PermissionController/res/values-be/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Адкрыццё спасылак"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Стандартныя для працы"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Стандартныя праграмы для прыватнай прасторы"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Аптымізаваныя для прылады"</string> + <string name="default_app_others" msgid="7793029848126079876">"Іншыя"</string> <string name="default_app_none" msgid="9084592086808194457">"Няма"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Стандартная сістэмная)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Няма праграм"</string> @@ -680,7 +678,7 @@ <string name="allow_restricted_settings" msgid="8073000189478396881">"Дазволіць абмежаваныя налады"</string> <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Налада з абмежаваным доступам"</string> <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"У мэтах бяспекі гэта налада цяпер недаступная."</string> - <string name="enhanced_confirmation_phone_state_dialog_title" msgid="5054064107559019689">"Не ўдаецца выканаць гэты дзеянне падчас выкліку"</string> + <string name="enhanced_confirmation_phone_state_dialog_title" msgid="5054064107559019689">"Нельга выканаць гэта дзеянне падчас выкліку"</string> <string name="enhanced_confirmation_phone_state_dialog_desc" msgid="5049619986796367451">"<xliff:g id="SETTING_DESCRIPTION">%1$s</xliff:g>\n\n Гэта налада заблакіравана для абароны вашай прылады і даных"</string> <string name="enhanced_confirmation_phone_state_dialog_install_desc_prefix" msgid="7153600694011441796">"Каб паспрабаваць усталяваць шкодныя праграмы, махляры могуць прасіць вас усталяваць невядомыя праграмы з новай крыніцы."</string> <string name="enhanced_confirmation_phone_state_dialog_a11y_desc_prefix" msgid="1086282331085551407">"Каб атрымаць кантроль над вашай прыладай, махляры могуць запытаць для праграмы доступ да спецыяльных магчымасцей."</string> diff --git a/PermissionController/res/values-bg/strings.xml b/PermissionController/res/values-bg/strings.xml index f3aea49e8..ce273f567 100644 --- a/PermissionController/res/values-bg/strings.xml +++ b/PermissionController/res/values-bg/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Отваряне на връзки"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"По подразбиране за работа"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Стандартни за частното пространство"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Оптимизирано за устройството"</string> + <string name="default_app_others" msgid="7793029848126079876">"Други"</string> <string name="default_app_none" msgid="9084592086808194457">"Няма"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Стандартно за системата)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Няма приложения"</string> diff --git a/PermissionController/res/values-bn/strings.xml b/PermissionController/res/values-bn/strings.xml index aff3af039..6572fa2c7 100644 --- a/PermissionController/res/values-bn/strings.xml +++ b/PermissionController/res/values-bn/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"লিঙ্ক খোলা"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"অফিসের জন্য ডিফল্ট"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"প্রাইভেট স্পেসের জন্য ডিফল্ট"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ডিভাইসের জন্য অপ্টিমাইজ করা হয়েছে"</string> + <string name="default_app_others" msgid="7793029848126079876">"অন্যান্য"</string> <string name="default_app_none" msgid="9084592086808194457">"কোনওটিই নয়"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(সিস্টেম ডিফল্ট)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"কোনও অ্যাপ নেই"</string> diff --git a/PermissionController/res/values-bs/strings.xml b/PermissionController/res/values-bs/strings.xml index 2003c9cf5..71c236fe9 100644 --- a/PermissionController/res/values-bs/strings.xml +++ b/PermissionController/res/values-bs/strings.xml @@ -441,7 +441,7 @@ <string name="default_apps_for_work" msgid="4970308943596201811">"Uobičajeno za rad"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Zadano za privatni prostor"</string> <string name="default_app_recommended" msgid="5669584821778942909">"Optimizirano za uređaj"</string> - <string name="default_app_others" msgid="7793029848126079876">"Ostalo"</string> + <string name="default_app_others" msgid="7793029848126079876">"Drugo"</string> <string name="default_app_none" msgid="9084592086808194457">"Nema"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Sistemski zadano)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Nema aplikacija"</string> diff --git a/PermissionController/res/values-ca/strings.xml b/PermissionController/res/values-ca/strings.xml index 3e9a02f85..6a10b3879 100644 --- a/PermissionController/res/values-ca/strings.xml +++ b/PermissionController/res/values-ca/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Obertura d\'enllaços"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Predeterminada per a la feina"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Predeterminades per a l\'espai privat"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimitzades per al dispositiu"</string> + <string name="default_app_others" msgid="7793029848126079876">"Altres"</string> <string name="default_app_none" msgid="9084592086808194457">"Cap"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Opció predeterminada del sistema)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Cap aplicació"</string> diff --git a/PermissionController/res/values-cs/strings.xml b/PermissionController/res/values-cs/strings.xml index a913ce1c2..a48d5afb9 100644 --- a/PermissionController/res/values-cs/strings.xml +++ b/PermissionController/res/values-cs/strings.xml @@ -383,7 +383,7 @@ <string name="role_emergency_search_keywords" msgid="1920007722599213358">"v případě nouze"</string> <string name="role_home_label" msgid="3871847846649769412">"Výchozí aplikace pro domácnost"</string> <string name="role_home_short_label" msgid="8544733747952272337">"Vstupní aplikace"</string> - <string name="role_home_description" msgid="7997371519626556675">"Aplikace (tzv. spouštěče), které nahrazují plochu na zařízení Android a dávají vám přístup\\nk obsahu a funkcím zařízení."</string> + <string name="role_home_description" msgid="7997371519626556675">"Aplikace (tzv. spouštěče), které nahrazují plochu na zařízení Android a dávají vám přístup k obsahu a funkcím zařízení."</string> <string name="role_home_request_title" msgid="738136983453341081">"Nastavit <xliff:g id="APP_NAME">%1$s</xliff:g> jako výchozí aplikaci pro domácnost?"</string> <string name="role_home_request_description" msgid="2658833966716057673">"Není potřeba žádné oprávnění"</string> <string name="role_home_search_keywords" msgid="3830755001192666285">"spouštěč"</string> @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Otevírání odkazů"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Výchozí pracovní"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Výchozí pro soukromý prostor"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimalizováno pro zařízení"</string> + <string name="default_app_others" msgid="7793029848126079876">"Jiné"</string> <string name="default_app_none" msgid="9084592086808194457">"Žádná aplikace"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Výchozí nastavení systému)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Žádné aplikace"</string> diff --git a/PermissionController/res/values-da/strings.xml b/PermissionController/res/values-da/strings.xml index c23e21cb6..67617fad9 100644 --- a/PermissionController/res/values-da/strings.xml +++ b/PermissionController/res/values-da/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Åbning af links"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Standard til arbejde"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Standard for privat område"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimeret til enheden"</string> + <string name="default_app_others" msgid="7793029848126079876">"Andre"</string> <string name="default_app_none" msgid="9084592086808194457">"Ingen"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Systemstandard)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Ingen apps"</string> diff --git a/PermissionController/res/values-de/strings.xml b/PermissionController/res/values-de/strings.xml index 1c47dffdc..75b4f7f46 100644 --- a/PermissionController/res/values-de/strings.xml +++ b/PermissionController/res/values-de/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Links öffnen"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Standard-Apps für Arbeit"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Standard-Apps für das vertrauliche Profil"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Für dein Gerät optimiert"</string> + <string name="default_app_others" msgid="7793029848126079876">"Sonstige"</string> <string name="default_app_none" msgid="9084592086808194457">"Keine"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(System-Standardeinstellung)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Keine Apps"</string> diff --git a/PermissionController/res/values-el/strings.xml b/PermissionController/res/values-el/strings.xml index f4d3bbd73..d361acbf7 100644 --- a/PermissionController/res/values-el/strings.xml +++ b/PermissionController/res/values-el/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Άνοιγμα συνδέσμων"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Προεπιλογή για εργασία"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Προεπιλογή για ιδιωτικό χώρο"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Βελτιστοποιημένες για τη συσκευή"</string> + <string name="default_app_others" msgid="7793029848126079876">"Άλλες"</string> <string name="default_app_none" msgid="9084592086808194457">"Καμία"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Προεπιλογή συστήματος)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Δεν υπάρχουν εφαρμογές"</string> diff --git a/PermissionController/res/values-en-rAU/strings.xml b/PermissionController/res/values-en-rAU/strings.xml index 979ed9c01..e57c8beec 100644 --- a/PermissionController/res/values-en-rAU/strings.xml +++ b/PermissionController/res/values-en-rAU/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Opening links"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Default for work"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Default for private space"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimised for device"</string> + <string name="default_app_others" msgid="7793029848126079876">"Others"</string> <string name="default_app_none" msgid="9084592086808194457">"None"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(System default)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"No apps"</string> diff --git a/PermissionController/res/values-en-rGB/strings.xml b/PermissionController/res/values-en-rGB/strings.xml index d5065668a..bce85d49c 100644 --- a/PermissionController/res/values-en-rGB/strings.xml +++ b/PermissionController/res/values-en-rGB/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Opening links"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Default for work"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Default for private space"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimised for device"</string> + <string name="default_app_others" msgid="7793029848126079876">"Others"</string> <string name="default_app_none" msgid="9084592086808194457">"None"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(System default)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"No apps"</string> diff --git a/PermissionController/res/values-en-rIN/strings.xml b/PermissionController/res/values-en-rIN/strings.xml index d5065668a..bce85d49c 100644 --- a/PermissionController/res/values-en-rIN/strings.xml +++ b/PermissionController/res/values-en-rIN/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Opening links"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Default for work"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Default for private space"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimised for device"</string> + <string name="default_app_others" msgid="7793029848126079876">"Others"</string> <string name="default_app_none" msgid="9084592086808194457">"None"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(System default)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"No apps"</string> diff --git a/PermissionController/res/values-es-rUS/strings.xml b/PermissionController/res/values-es-rUS/strings.xml index f10410f6d..cecd1771a 100644 --- a/PermissionController/res/values-es-rUS/strings.xml +++ b/PermissionController/res/values-es-rUS/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Abrir vínculos"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Predeterminadas de trabajo"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Configuración predeterminada del espacio privado"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimizadas para el dispositivo"</string> + <string name="default_app_others" msgid="7793029848126079876">"Otros"</string> <string name="default_app_none" msgid="9084592086808194457">"Ninguna"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Predeterminada del sistema)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Sin apps"</string> diff --git a/PermissionController/res/values-es/strings.xml b/PermissionController/res/values-es/strings.xml index 7ebed6d43..8078fbf87 100644 --- a/PermissionController/res/values-es/strings.xml +++ b/PermissionController/res/values-es/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Abrir enlaces"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Predeterminadas para trabajo"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Predeterminadas para el espacio privado"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimizadas para el dispositivo"</string> + <string name="default_app_others" msgid="7793029848126079876">"Otras"</string> <string name="default_app_none" msgid="9084592086808194457">"Ninguna"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Predeterminado del sistema)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"No hay aplicaciones"</string> diff --git a/PermissionController/res/values-eu/strings.xml b/PermissionController/res/values-eu/strings.xml index bfe5e0a2a..5b60129e9 100644 --- a/PermissionController/res/values-eu/strings.xml +++ b/PermissionController/res/values-eu/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Irekiko diren estekak"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Lanerako aplikazio lehenetsiak"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Eremu pribatuko aplikazio lehenetsiak"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Gailurako optimizatuta"</string> + <string name="default_app_others" msgid="7793029848126079876">"Beste batzuk"</string> <string name="default_app_none" msgid="9084592086808194457">"Bat ere ez"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(sistemaren aplikazio lehenetsia)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Ez dago aplikaziorik"</string> diff --git a/PermissionController/res/values-fa/strings.xml b/PermissionController/res/values-fa/strings.xml index 20f7477b2..53f94f4c9 100644 --- a/PermissionController/res/values-fa/strings.xml +++ b/PermissionController/res/values-fa/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"باز کردن پیوندها"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"پیشفرض برای کار"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"برنامههای پیشفرض برای فضای خصوصی"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"بهینهسازیشده برای دستگاه"</string> + <string name="default_app_others" msgid="7793029848126079876">"موارد دیگر"</string> <string name="default_app_none" msgid="9084592086808194457">"هیچکدام"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(پیشفرض سیستم)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"برنامهای موجود نیست"</string> diff --git a/PermissionController/res/values-fi/strings.xml b/PermissionController/res/values-fi/strings.xml index 0d866a517..1a9029bfa 100644 --- a/PermissionController/res/values-fi/strings.xml +++ b/PermissionController/res/values-fi/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Linkkien avaaminen"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Työkäytön oletus"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Oletus yksityiselle tilalle"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimoitu laitteelle"</string> + <string name="default_app_others" msgid="7793029848126079876">"Muut"</string> <string name="default_app_none" msgid="9084592086808194457">"Ei mitään"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Järjestelmän oletusarvo)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Ei sovelluksia"</string> diff --git a/PermissionController/res/values-fr-rCA/strings.xml b/PermissionController/res/values-fr-rCA/strings.xml index b428347ba..c8936db35 100644 --- a/PermissionController/res/values-fr-rCA/strings.xml +++ b/PermissionController/res/values-fr-rCA/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Ouverture des liens"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Par défaut pour util. profess."</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Applis par défaut pour l\'Espace privé"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimisée pour l\'appareil"</string> + <string name="default_app_others" msgid="7793029848126079876">"Autres"</string> <string name="default_app_none" msgid="9084592086808194457">"Aucune"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Paramètre(s) système par défaut)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Aucune appli"</string> diff --git a/PermissionController/res/values-fr/strings.xml b/PermissionController/res/values-fr/strings.xml index f352ba74a..10057977b 100644 --- a/PermissionController/res/values-fr/strings.xml +++ b/PermissionController/res/values-fr/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Ouverture des liens"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Par défaut pour utilisation pro"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Paramètres par défaut d\'Espace privé"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimisées pour l\'appareil"</string> + <string name="default_app_others" msgid="7793029848126079876">"Autres"</string> <string name="default_app_none" msgid="9084592086808194457">"Aucune"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Application système par défaut)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Aucune application"</string> diff --git a/PermissionController/res/values-gl/strings.xml b/PermissionController/res/values-gl/strings.xml index dbbff57d7..aef51eaa4 100644 --- a/PermissionController/res/values-gl/strings.xml +++ b/PermissionController/res/values-gl/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Apertura de ligazóns"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Predeterminadas para o traballo"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Aplicacións predeterminadas do espazo privado"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimizadas para o dispositivo"</string> + <string name="default_app_others" msgid="7793029848126079876">"Outras"</string> <string name="default_app_none" msgid="9084592086808194457">"Ningunha"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Opción predeterminada do sistema)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Non hai ningunha aplicación"</string> diff --git a/PermissionController/res/values-gu/strings.xml b/PermissionController/res/values-gu/strings.xml index 321eb2066..8e43211c2 100644 --- a/PermissionController/res/values-gu/strings.xml +++ b/PermissionController/res/values-gu/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"લિંક ખોલવી"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"કાર્ય માટે ડિફૉલ્ટ"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ખાનગી સ્પેસ માટે ડિફૉલ્ટ"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ડિવાઇસ માટે ઑપ્ટિમાઇઝ કરેલી છે"</string> + <string name="default_app_others" msgid="7793029848126079876">"અન્ય"</string> <string name="default_app_none" msgid="9084592086808194457">"કોઈ નહીં"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(સિસ્ટમ ડિફૉલ્ટ)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"કોઈ ઍપ નથી"</string> diff --git a/PermissionController/res/values-hi/strings.xml b/PermissionController/res/values-hi/strings.xml index 5e9a9be69..59034f2a1 100644 --- a/PermissionController/res/values-hi/strings.xml +++ b/PermissionController/res/values-hi/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"खुलने वाले लिंक"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"काम के लिए डिफ़ॉल्ट"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"प्राइवेट स्पेस के लिए डिफ़ॉल्ट ऐप्लिकेशन"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"डिवाइस के लिए ऑप्टिमाइज़ किया गया"</string> + <string name="default_app_others" msgid="7793029848126079876">"अन्य"</string> <string name="default_app_none" msgid="9084592086808194457">"कोई नहीं"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(सिस्टम डिफ़ॉल्ट)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"कोई ऐप्लिकेशन नहीं"</string> diff --git a/PermissionController/res/values-hu/strings.xml b/PermissionController/res/values-hu/strings.xml index 543067d60..038f0161f 100644 --- a/PermissionController/res/values-hu/strings.xml +++ b/PermissionController/res/values-hu/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Linkek megnyitása"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Munkahelyi alapértelmezett"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Alapértelmezett a magánterületnél"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Az eszközre optimalizálva"</string> + <string name="default_app_others" msgid="7793029848126079876">"Egyéb"</string> <string name="default_app_none" msgid="9084592086808194457">"Nincs"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Alapértelmezett)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Nincs alkalmazás"</string> @@ -497,7 +495,7 @@ <string name="permgrouprequest_coarselocation_imagetext" msgid="8650605041483025297">"Hozzávetőleges"</string> <string name="permgrouprequest_calendar" msgid="1493150855673603806">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára, hogy hozzáférjen a naptárhoz?"</string> <string name="permgrouprequest_device_aware_calendar" msgid="7161929851377463612">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára, hogy hozzáférjen a naptárához ezen az eszközön: <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g>’s</b>?"</string> - <string name="permgrouprequest_sms" msgid="5672063688745420991">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára, hogy SMS-eket küldhessen és tekinthessen meg?"</string> + <string name="permgrouprequest_sms" msgid="5672063688745420991">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára SMS-ek küldését és megtekintését?"</string> <string name="permgrouprequest_device_aware_sms" msgid="6639977653040502291">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára az SMS-ek küldését és megtekintését ezen az eszközön: <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_storage" msgid="8717773092518621602">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára, hogy hozzáférjen az eszközön tárolt fotókhoz, médiatartalmakhoz és fájlokhoz?"</string> <string name="permgrouprequest_device_aware_storage" msgid="6933251810928606636">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára, hogy fotókhoz, médiatartalmakhoz és fájlokhoz férjen hozzá ezen az eszközön: <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> diff --git a/PermissionController/res/values-in/strings.xml b/PermissionController/res/values-in/strings.xml index 9f05ee8e5..2dc9d5f21 100644 --- a/PermissionController/res/values-in/strings.xml +++ b/PermissionController/res/values-in/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Membuka link"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Default untuk kerja"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Default untuk ruang privasi"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Dioptimalkan untuk perangkat"</string> + <string name="default_app_others" msgid="7793029848126079876">"Lainnya"</string> <string name="default_app_none" msgid="9084592086808194457">"Tidak ada"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Default sistem)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Tidak ada aplikasi"</string> @@ -680,11 +678,11 @@ <string name="allow_restricted_settings" msgid="8073000189478396881">"Izinkan setelan terbatas"</string> <string name="enhanced_confirmation_dialog_title" msgid="7562437438040966351">"Setelan terbatas"</string> <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"Demi keamanan Anda, setelan ini tidak tersedia untuk saat ini."</string> - <string name="enhanced_confirmation_phone_state_dialog_title" msgid="5054064107559019689">"Tidak dapat menyelesaikan tindakan selama panggilan"</string> + <string name="enhanced_confirmation_phone_state_dialog_title" msgid="5054064107559019689">"Tidak bisa selesaikan tindakan selama panggilan"</string> <string name="enhanced_confirmation_phone_state_dialog_desc" msgid="5049619986796367451">"<xliff:g id="SETTING_DESCRIPTION">%1$s</xliff:g>\n\n Setelan ini diblokir untuk melindungi perangkat dan data Anda"</string> - <string name="enhanced_confirmation_phone_state_dialog_install_desc_prefix" msgid="7153600694011441796">"Penipu mungkin mencoba menginstal aplikasi berbahaya dengan meminta Anda menginstal aplikasi tidak dikenal dari sumber baru."</string> - <string name="enhanced_confirmation_phone_state_dialog_a11y_desc_prefix" msgid="1086282331085551407">"Penipu mungkin mencoba mengambil kendali perangkat Anda dengan meminta Anda mengizinkan akses aksesibilitas untuk suatu aplikasi."</string> - <string name="enhanced_confirmation_phone_state_dialog_generic_desc_prefix" msgid="8141411486179553156">"Penipu mungkin mencoba membahayakan perangkat Anda dengan setelan ini."</string> + <string name="enhanced_confirmation_phone_state_dialog_install_desc_prefix" msgid="7153600694011441796">"Scammer mungkin mencoba menginstal aplikasi berbahaya dengan meminta Anda menginstal aplikasi tidak dikenal dari sumber baru."</string> + <string name="enhanced_confirmation_phone_state_dialog_a11y_desc_prefix" msgid="1086282331085551407">"Scammer mungkin mencoba mengambil kendali perangkat Anda dengan meminta Anda mengizinkan akses aksesibilitas untuk suatu aplikasi."</string> + <string name="enhanced_confirmation_phone_state_dialog_generic_desc_prefix" msgid="8141411486179553156">"Scammer mungkin mencoba membahayakan perangkat Anda dengan setelan ini."</string> <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"Aplikasi ditolak aksesnya ke <xliff:g id="PERMISSION_NAME">%1$s</xliff:g>"</string> <string name="enhanced_confirmation_dialog_desc_permission" msgid="3150778951946468945">"Aplikasi meminta akses ke izin sensitif yang dapat membahayakan info pribadi dan keuangan Anda.<xliff:g id="ID_1"><br><br></xliff:g>Aplikasi mungkin tidak dapat berfungsi dengan baik tanpa izin terbatas ini. <a href=<xliff:g id="LEARN_MORE_LINK">%1$s</xliff:g>&gtPelajari cara mengizinkan akses</a>"</string> <string name="enhanced_confirmation_dialog_title_role" msgid="1737023798483772780">"Aplikasi ditolak aksesnya untuk menjadi <xliff:g id="ROLE_NAME">%1$s</xliff:g> default"</string> diff --git a/PermissionController/res/values-is/strings.xml b/PermissionController/res/values-is/strings.xml index 398198793..9d9f68535 100644 --- a/PermissionController/res/values-is/strings.xml +++ b/PermissionController/res/values-is/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Opnun tengla"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Sjálfgefið fyrir vinnu"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Sjálfgefið fyrir leynirými"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Fínstillt fyrir tæki"</string> + <string name="default_app_others" msgid="7793029848126079876">"Annað"</string> <string name="default_app_none" msgid="9084592086808194457">"Ekkert"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Sjálfgildi kerfis)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Engin forrit"</string> diff --git a/PermissionController/res/values-iw/strings.xml b/PermissionController/res/values-iw/strings.xml index 1d1440e21..df90d3297 100644 --- a/PermissionController/res/values-iw/strings.xml +++ b/PermissionController/res/values-iw/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"פתיחת קישורים"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"ברירת מחדל לעבודה"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ברירת מחדל עבור המרחב הפרטי"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"מותאמות למכשיר"</string> + <string name="default_app_others" msgid="7793029848126079876">"אחרות"</string> <string name="default_app_none" msgid="9084592086808194457">"ללא"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(ברירת מחדל של המערכת)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"אין אפליקציות"</string> @@ -477,7 +475,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-ja/strings.xml b/PermissionController/res/values-ja/strings.xml index 43e204b69..0be93d464 100644 --- a/PermissionController/res/values-ja/strings.xml +++ b/PermissionController/res/values-ja/strings.xml @@ -491,8 +491,8 @@ <string name="permgrouprequest_device_aware_fineupgrade" msgid="4453775952305587571">"<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>の位置情報に対する <b><xliff:g id="APP_NAME"><b>%1$s</b></xliff:g></b> のアクセス権を「おおよそ」から「正確」に変更しますか?"</string> <string name="permgrouprequest_coarselocation" msgid="7244605063736425232">"このデバイスのおおよその位置情報へのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_device_aware_coarselocation" msgid="8367540370912066757">"<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>のおおよその位置情報へのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> - <string name="permgrouprequest_finelocation_imagetext" msgid="1313062433398914334">"正確"</string> - <string name="permgrouprequest_coarselocation_imagetext" msgid="8650605041483025297">"おおよそ"</string> + <string name="permgrouprequest_finelocation_imagetext" msgid="1313062433398914334">"正確な位置"</string> + <string name="permgrouprequest_coarselocation_imagetext" msgid="8650605041483025297">"おおよその位置"</string> <string name="permgrouprequest_calendar" msgid="1493150855673603806">"カレンダーへのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> <string name="permgrouprequest_device_aware_calendar" msgid="7161929851377463612">"<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>内のカレンダーへのアクセスを <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に許可しますか?"</string> <string name="permgrouprequest_sms" msgid="5672063688745420991">"SMS メッセージの送信と表示を「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> diff --git a/PermissionController/res/values-ka/strings.xml b/PermissionController/res/values-ka/strings.xml index 69104a55e..c99cf319d 100644 --- a/PermissionController/res/values-ka/strings.xml +++ b/PermissionController/res/values-ka/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"ბმულების გახსნა"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"ნაგულისხმევი სამსახურისთვის"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"კერძო სივრცისთვის ნაგულისხმევი აპები"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ოპტიმიზებულია მოწყობილობისთვის"</string> + <string name="default_app_others" msgid="7793029848126079876">"სხვა"</string> <string name="default_app_none" msgid="9084592086808194457">"არცერთი"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(სისტემის ნაგულისხმევი)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"აპები არ არის"</string> diff --git a/PermissionController/res/values-kk/strings.xml b/PermissionController/res/values-kk/strings.xml index 81d897a37..817361573 100644 --- a/PermissionController/res/values-kk/strings.xml +++ b/PermissionController/res/values-kk/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Сілтемелер ашу"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Жұмыс үшін әдепкі қолданба"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Құпия кеңістікке арналған әдепкі қолданбалар"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Құрылғы үшін оңтайландырылған"</string> + <string name="default_app_others" msgid="7793029848126079876">"Басқа"</string> <string name="default_app_none" msgid="9084592086808194457">"Жоқ"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(жүйенің әдепкі қолданбасы)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Қолданба жоқ"</string> diff --git a/PermissionController/res/values-km/strings.xml b/PermissionController/res/values-km/strings.xml index 5f5519c7c..d7710e353 100644 --- a/PermissionController/res/values-km/strings.xml +++ b/PermissionController/res/values-km/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"ការបើកតំណ"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"លំនាំដើមសម្រាប់ការងារ"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"លំនាំដើមសម្រាប់លំហឯកជន"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"បានបង្កើនប្រសិទ្ធភាពសម្រាប់ឧបករណ៍"</string> + <string name="default_app_others" msgid="7793029848126079876">"ផ្សេងទៀត"</string> <string name="default_app_none" msgid="9084592086808194457">"គ្មាន"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(លំនាំដើមប្រព័ន្ធ)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"គ្មានកម្មវិធីទេ"</string> diff --git a/PermissionController/res/values-kn/strings.xml b/PermissionController/res/values-kn/strings.xml index f9f4c63f8..b613cf5d4 100644 --- a/PermissionController/res/values-kn/strings.xml +++ b/PermissionController/res/values-kn/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"ಲಿಂಕ್ಗಳನ್ನು ತೆರೆಯುವುದು"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"ಕೆಲಸದ ಕುರಿತಾದ ಡೀಫಾಲ್ಟ್ ಆ್ಯಪ್"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ಪ್ರೈವೆಟ್ ಸ್ಪೇಸ್ನ ಡೀಫಾಲ್ಟ್"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ಸಾಧನಕ್ಕಾಗಿ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</string> + <string name="default_app_others" msgid="7793029848126079876">"ಇತರೆ"</string> <string name="default_app_none" msgid="9084592086808194457">"ಯಾವುದೂ ಬೇಡ"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"ಯಾವುದೇ ಆ್ಯಪ್ಗಳು ಇಲ್ಲ"</string> diff --git a/PermissionController/res/values-ko/strings.xml b/PermissionController/res/values-ko/strings.xml index 5ee3a3b7a..c58b2e98a 100644 --- a/PermissionController/res/values-ko/strings.xml +++ b/PermissionController/res/values-ko/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"링크 열기"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"직장용 기본 앱"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"비공개 스페이스의 기본값"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"기기에 최적화된 앱"</string> + <string name="default_app_others" msgid="7793029848126079876">"기타"</string> <string name="default_app_none" msgid="9084592086808194457">"없음"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(시스템 기본값)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"앱 없음"</string> diff --git a/PermissionController/res/values-ky/strings.xml b/PermissionController/res/values-ky/strings.xml index 9196cc7ce..4cc2b1c9f 100644 --- a/PermissionController/res/values-ky/strings.xml +++ b/PermissionController/res/values-ky/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Шилтемелерди ачуу"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Жумуш үчүн демейки жөндөөлөр"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Жеке мейкиндик үчүн демейки колдонмолор"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Түзмөккө оптималдаштырылды"</string> + <string name="default_app_others" msgid="7793029848126079876">"Башкалар"</string> <string name="default_app_none" msgid="9084592086808194457">"Жок"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Демейки тутум)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Бир да колдонмо жок"</string> diff --git a/PermissionController/res/values-lv/strings.xml b/PermissionController/res/values-lv/strings.xml index 2d45c7c1e..8829ee0da 100644 --- a/PermissionController/res/values-lv/strings.xml +++ b/PermissionController/res/values-lv/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Saišu atvēršana"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Noklusējuma iestatījums darbam"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Noklusējums privātajai telpai"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimizētas ierīcei"</string> + <string name="default_app_others" msgid="7793029848126079876">"Citas"</string> <string name="default_app_none" msgid="9084592086808194457">"Nav"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Sistēmas noklusējums)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Nav lietotņu"</string> diff --git a/PermissionController/res/values-mk/strings.xml b/PermissionController/res/values-mk/strings.xml index 009d6b722..d8ba89c77 100644 --- a/PermissionController/res/values-mk/strings.xml +++ b/PermissionController/res/values-mk/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"За отворање линкови"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Стандардно за работа"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Стандардно за „Приватен простор“"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Оптимизирано за уредот"</string> + <string name="default_app_others" msgid="7793029848126079876">"Други"</string> <string name="default_app_none" msgid="9084592086808194457">"Нема"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Стандардно за системот)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Нема апликации"</string> @@ -630,7 +628,7 @@ <string name="safety_center_background_location_access_reminder_summary" msgid="7431657777510537658">"Апликацијава може секогаш да пристапува до вашата локација, дури и кога е затворена.\n\nНа одредени апликации за безбедност и итни случаи им е потребен пристап до вашата локација во заднината за правилно да функционираат."</string> <string name="safety_center_background_location_access_revoked" msgid="6972274943343442213">"Пристапот е променет"</string> <string name="safety_center_view_recent_location_access" msgid="3524391299490678243">"Погледнете го неодамнешното користење на локацијата"</string> - <string name="privacy_controls_title" msgid="7605929972256835199">"Контроли на приватноста"</string> + <string name="privacy_controls_title" msgid="7605929972256835199">"Контроли за приватност"</string> <string name="camera_toggle_title" msgid="1251201397431837666">"Пристап до камерата"</string> <string name="mic_toggle_title" msgid="2649991093496110162">"Пристап до микрофонот"</string> <string name="perm_toggle_description" msgid="7801326363741451379">"За апликации и услуги"</string> diff --git a/PermissionController/res/values-mn/strings.xml b/PermissionController/res/values-mn/strings.xml index 9838569ac..d85eddc45 100644 --- a/PermissionController/res/values-mn/strings.xml +++ b/PermissionController/res/values-mn/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Холбоосыг нээх сонголт"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Ажлын өгөгдмөл апп"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Хаалттай орон зайн өгөгдмөл"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Төхөөрөмжид зориулж оновчилсон"</string> + <string name="default_app_others" msgid="7793029848126079876">"Бусад"</string> <string name="default_app_none" msgid="9084592086808194457">"Тохируулсан апп алга"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Системийн өгөгдмөл)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Апп алга"</string> diff --git a/PermissionController/res/values-mr/strings.xml b/PermissionController/res/values-mr/strings.xml index 4a280b6fd..538dd424f 100644 --- a/PermissionController/res/values-mr/strings.xml +++ b/PermissionController/res/values-mr/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"उघडणार्या लिंक"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"कार्यासाठी डीफॉल्ट"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"खाजगी स्पेससाठी डीफॉल्ट"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ऑप्टिमाइझ केलेले डिव्हाइस"</string> + <string name="default_app_others" msgid="7793029848126079876">"इतर"</string> <string name="default_app_none" msgid="9084592086808194457">"काहीही नाही"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(सिस्टम डीफॉल्ट)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"अॅप्स नाहीत"</string> diff --git a/PermissionController/res/values-my/strings.xml b/PermissionController/res/values-my/strings.xml index 662a5f887..441769416 100644 --- a/PermissionController/res/values-my/strings.xml +++ b/PermissionController/res/values-my/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"လင့်ခ်များကို ဖွင့်ခြင်း"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"အလုပ်အတွက် မူရင်း"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"သီးသန့်နေရာအတွက် မူလအက်ပ်များ"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"စက်အတွက် အကောင်းဆုံးပြင်ထားသည်"</string> + <string name="default_app_others" msgid="7793029848126079876">"အခြား"</string> <string name="default_app_none" msgid="9084592086808194457">"မရှိ"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(စနစ်မူရင်း)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"အက်ပ် မရှိပါ"</string> diff --git a/PermissionController/res/values-nb/strings.xml b/PermissionController/res/values-nb/strings.xml index fd8467d47..3835d7573 100644 --- a/PermissionController/res/values-nb/strings.xml +++ b/PermissionController/res/values-nb/strings.xml @@ -440,12 +440,10 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Åpning av linker"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Jobbstandard"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Standard for privat område"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimalisert for enheten"</string> + <string name="default_app_others" msgid="7793029848126079876">"Andre"</string> <string name="default_app_none" msgid="9084592086808194457">"Ingen"</string> - <string name="default_app_system_default" msgid="6218386768175513760">"(System-&shy;standard)"</string> + <string name="default_app_system_default" msgid="6218386768175513760">"(System-&#173;standard)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Ingen apper"</string> <string name="default_payment_app_other_nfc_services" msgid="5957633798695758917">"Andre NFC-tjenester"</string> <string name="car_default_app_selected" msgid="5416420830430644174">"Valgt"</string> diff --git a/PermissionController/res/values-ne/strings.xml b/PermissionController/res/values-ne/strings.xml index e15676c9a..a2c9dee59 100644 --- a/PermissionController/res/values-ne/strings.xml +++ b/PermissionController/res/values-ne/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"लिंकहरू खोल्दा"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"कार्यका लागि डिफल्ट"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"निजी स्पेसका लागि डिफल्ट एपहरू"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"यो डिभाइसका लागि अप्टिमाइज गरिएका"</string> + <string name="default_app_others" msgid="7793029848126079876">"अन्य"</string> <string name="default_app_none" msgid="9084592086808194457">"कुनै पनि होइन"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(सिस्टम डिफल्ट)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"कुनै पनि एप छैन"</string> diff --git a/PermissionController/res/values-nl/strings.xml b/PermissionController/res/values-nl/strings.xml index 1108057cb..5437c3c7e 100644 --- a/PermissionController/res/values-nl/strings.xml +++ b/PermissionController/res/values-nl/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Links openen"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Standaard voor werk"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Standaard voor privégedeelte"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Geoptimaliseerd voor apparaat"</string> + <string name="default_app_others" msgid="7793029848126079876">"Anders"</string> <string name="default_app_none" msgid="9084592086808194457">"Geen"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Systeemstandaard)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Geen apps"</string> diff --git a/PermissionController/res/values-or/strings.xml b/PermissionController/res/values-or/strings.xml index 296b2c113..3a9713fbd 100644 --- a/PermissionController/res/values-or/strings.xml +++ b/PermissionController/res/values-or/strings.xml @@ -52,7 +52,7 @@ <string name="permission_revoked_none" msgid="9213345075484381180">"କୌଣସି ଅନୁମତି ଅକ୍ଷମ କରାଯାଇନାହିଁ"</string> <string name="grant_dialog_button_allow" msgid="5314677880021102550">"ଅନୁମତି ଦିଅନ୍ତୁ"</string> <string name="grant_dialog_button_allow_always" msgid="4485552579273565981">"ସବୁବେଳେ ଅନୁମତି ଦିଅନ୍ତୁ"</string> - <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"ଆପ୍ ବ୍ୟବହାର କରିବା ସମୟରେ"</string> + <string name="grant_dialog_button_allow_foreground" msgid="501896824973636533">"ଆପ ବ୍ୟବହାର କରିବା ସମୟରେ"</string> <string name="grant_dialog_button_change_to_precise_location" msgid="3273115879467236033">"ସଠିକ୍ ଲୋକେସନକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string> <string name="grant_dialog_button_keey_approximate_location" msgid="438025182769080011">"ଆନୁମାନିକ ଲୋକେସନ୍ ରଖନ୍ତୁ"</string> <string name="grant_dialog_button_allow_one_time" msgid="2618088516449706391">"କେବଳ ଏହି ସମୟ ପାଇଁ"</string> @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"ଓପନିଂ ଲିଙ୍କ୍"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"କାର୍ଯ୍ୟ ପାଇଁ ଡିଫଲ୍ଟ ଅଛି"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ପ୍ରାଇଭେଟ ସ୍ପେସ ପାଇଁ ଡିଫଲ୍ଟ"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ଡିଭାଇସ ପାଇଁ ଅପ୍ଟିମାଇଜ କରାଯାଇଛି"</string> + <string name="default_app_others" msgid="7793029848126079876">"ଅନ୍ୟ"</string> <string name="default_app_none" msgid="9084592086808194457">"କିଛି ଆପ ସେଟ କରାଯାଇନାହିଁ"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(ସିଷ୍ଟମ୍ ଡିଫଲ୍ଟ)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"କୌଣସି ଆପ୍ ନାହିଁ"</string> @@ -493,7 +491,7 @@ <string name="permgrouprequest_device_aware_fineupgrade" msgid="4453775952305587571">"<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>ରେ <xliff:g id="APP_NAME"><b>%1$s</b></xliff:g>ର ଲୋକେସନ ଆକ୍ସେସକୁ ଆନୁମାନିକରୁ ସଠିକକୁ ପରିବର୍ତ୍ତନ କରିବେ?"</string> <string name="permgrouprequest_coarselocation" msgid="7244605063736425232">"ଏହି ଡିଭାଇସର ଆନୁମାନିକ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିବା ପାଇଁ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ ଅନୁମତି ଦେବେ?"</string> <string name="permgrouprequest_device_aware_coarselocation" msgid="8367540370912066757">"<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>ର ଆନୁମାନିକ ଲୋକେସନକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ ଅନୁମତି ଦେବେ?"</string> - <string name="permgrouprequest_finelocation_imagetext" msgid="1313062433398914334">"ସଠିକ୍"</string> + <string name="permgrouprequest_finelocation_imagetext" msgid="1313062433398914334">"ସଠିକ"</string> <string name="permgrouprequest_coarselocation_imagetext" msgid="8650605041483025297">"(ଆନୁମାନିକ)"</string> <string name="permgrouprequest_calendar" msgid="1493150855673603806">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍କୁ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string> <string name="permgrouprequest_device_aware_calendar" msgid="7161929851377463612">"<b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>ରେ ଆପଣଙ୍କ କେଲେଣ୍ଡରକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ ଅନୁମତି ଦେବେ?"</string> diff --git a/PermissionController/res/values-pa/strings.xml b/PermissionController/res/values-pa/strings.xml index 8ca8a4b56..20f910f74 100644 --- a/PermissionController/res/values-pa/strings.xml +++ b/PermissionController/res/values-pa/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"ਖੁੱਲ੍ਹਣ ਵਾਲੇ ਲਿੰਕ"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"ਕੰਮ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ਪ੍ਰਾਈਵੇਟ ਸਪੇਸ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ਡੀਵਾਈਸ ਲਈ ਸੁਯੋਗ ਬਣਾਈਆਂ"</string> + <string name="default_app_others" msgid="7793029848126079876">"ਹੋਰ"</string> <string name="default_app_none" msgid="9084592086808194457">"ਕੋਈ ਨਹੀਂ"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(ਸਿਸਟਮ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"ਕੋਈ ਐਪਾਂ ਨਹੀਂ"</string> @@ -477,7 +475,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-pl/strings.xml b/PermissionController/res/values-pl/strings.xml index 6b5a936f5..0aefe4a69 100644 --- a/PermissionController/res/values-pl/strings.xml +++ b/PermissionController/res/values-pl/strings.xml @@ -348,7 +348,7 @@ <string name="no_apps_allowed" msgid="7718822655254468631">"Nie zezwolono żadnym aplikacjom"</string> <string name="no_apps_allowed_full" msgid="8011716991498934104">"Brak aplikacji z uprawnieniami dla wszystkich plików"</string> <string name="no_apps_allowed_scoped" msgid="4908850477787659501">"Brak aplikacji z uprawnieniami tylko dla multimediów"</string> - <string name="no_apps_denied" msgid="7663435886986784743">"Nie zabroniono dostępu żadnym aplikacjom"</string> + <string name="no_apps_denied" msgid="7663435886986784743">"Nie odmówiono dostępu żadnym aplikacjom"</string> <string name="car_permission_selected" msgid="180837028920791596">"Wybrana"</string> <string name="settings" msgid="5409109923158713323">"Ustawienia"</string> <string name="accessibility_service_dialog_title_single" msgid="7956432823014102366">"Usługa <xliff:g id="SERVICE_NAME">%s</xliff:g> ma pełny dostęp do urządzenia"</string> @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Otwieranie linków"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Domyślne do pracy"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Domyślne dla przestrzeni prywatnej"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Zoptymalizowane dla danego urządzenia"</string> + <string name="default_app_others" msgid="7793029848126079876">"Inne"</string> <string name="default_app_none" msgid="9084592086808194457">"Brak"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Domyślna aplikacja systemowa)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Brak aplikacji"</string> diff --git a/PermissionController/res/values-ro/strings.xml b/PermissionController/res/values-ro/strings.xml index 83a797894..34e100173 100644 --- a/PermissionController/res/values-ro/strings.xml +++ b/PermissionController/res/values-ro/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Deschiderea linkurilor"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Prestabilite pentru serviciu"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Prestabilit pentru spațiul privat"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimizate pentru dispozitiv"</string> + <string name="default_app_others" msgid="7793029848126079876">"Altele"</string> <string name="default_app_none" msgid="9084592086808194457">"Niciuna"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Prestabilită de sistem)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Nicio aplicație"</string> @@ -477,7 +475,7 @@ <string name="permgrouprequest_device_aware_storage_isolated" msgid="6463062962458809752">"Permiți accesul <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> la fotografiile și conținutul media de pe <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequest_contacts" msgid="8391550064551053695">"Permiți ca <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> să-ți acceseze agenda?"</string> <string name="permgrouprequest_device_aware_contacts" msgid="731025863972535928">"Permiți ca <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> să acceseze agenda ta de pe <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> - <string name="permgrouprequest_location" msgid="6990232580121067883">"Permiți ca <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> să acceseze locația acestui dispozitiv?"</string> + <string name="permgrouprequest_location" msgid="6990232580121067883">"Permiți accesarea de către <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> a locației acestui dispozitiv?"</string> <string name="permgrouprequest_device_aware_location" msgid="6075412127429878638">"Permiți ca <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> să acceseze locația dispozitivului <b><xliff:g id="DEVICE_NAME">%2$s</xliff:g></b>?"</string> <string name="permgrouprequestdetail_location" msgid="2635935335778429894">"Aplicația va avea acces la locație doar când o folosești"</string> <string name="permgroupbackgroundrequest_location" msgid="1085680897265734809">"Permiți ca <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> să acceseze locația acestui dispozitiv?"</string> diff --git a/PermissionController/res/values-ru-v33/strings.xml b/PermissionController/res/values-ru-v33/strings.xml index b45662712..5506ccd97 100644 --- a/PermissionController/res/values-ru-v33/strings.xml +++ b/PermissionController/res/values-ru-v33/strings.xml @@ -41,7 +41,7 @@ <string name="safety_center_qs_privacy_control" msgid="1160682635058529673">"Переключатель: <xliff:g id="PRIVACY_CONTROL_TITLE">%1$s</xliff:g> (<xliff:g id="PRIVACY_CONTROL_STATUS">%2$s</xliff:g>)"</string> <string name="safety_center_qs_toggle_action" msgid="5920465736488119255">"Переключатель"</string> <string name="safety_center_qs_open_action" msgid="2760200829912423728">"Открыть"</string> - <string name="safety_center_review_settings_button" msgid="938981137942443930">"Перейти в настройки"</string> + <string name="safety_center_review_settings_button" msgid="938981137942443930">"Открыть настройки"</string> <string name="safety_center_gear_label" msgid="5175877094379694098">"Настройки"</string> <string name="safety_center_info_label" msgid="8993181584061825412">"Информация"</string> </resources> diff --git a/PermissionController/res/values-ru/strings.xml b/PermissionController/res/values-ru/strings.xml index daf33a6c6..1fef844fe 100644 --- a/PermissionController/res/values-ru/strings.xml +++ b/PermissionController/res/values-ru/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Переход по ссылкам"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Стандартные для работы"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Приложения по умолчанию для личного пространства"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Оптимизированные для устройства"</string> + <string name="default_app_others" msgid="7793029848126079876">"Прочие"</string> <string name="default_app_none" msgid="9084592086808194457">"Нет"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(по умолчанию)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Приложений нет"</string> diff --git a/PermissionController/res/values-si/strings.xml b/PermissionController/res/values-si/strings.xml index 04c2feee5..bb8239cb6 100644 --- a/PermissionController/res/values-si/strings.xml +++ b/PermissionController/res/values-si/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"සබැඳි විවෘත කිරීම"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"වැඩ සඳහා පෙරනිමි"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"රහසිගත අවකාශය සඳහා පෙරනිමිය"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"උපාංගය සඳහා ප්රශස්ත කර ඇත"</string> + <string name="default_app_others" msgid="7793029848126079876">"වෙනත්"</string> <string name="default_app_none" msgid="9084592086808194457">"කිසිවක් නැත"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(පද්ධතිය පෙරනිමි)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"යෙදුම් නොමැත"</string> diff --git a/PermissionController/res/values-sk/strings.xml b/PermissionController/res/values-sk/strings.xml index 5a026bca4..92dccece6 100644 --- a/PermissionController/res/values-sk/strings.xml +++ b/PermissionController/res/values-sk/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Otváranie odkazov"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Predvolené na prácu"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Predvolené pre súkromný priestor"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimalizované pre zariadenie"</string> + <string name="default_app_others" msgid="7793029848126079876">"Iné"</string> <string name="default_app_none" msgid="9084592086808194457">"Žiadna aplikácia"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Predvolené systémom)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Žiadne aplikácie"</string> diff --git a/PermissionController/res/values-sl/strings.xml b/PermissionController/res/values-sl/strings.xml index 3e825d309..103ffbee7 100644 --- a/PermissionController/res/values-sl/strings.xml +++ b/PermissionController/res/values-sl/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Odpiranje povezav"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Privzeto za delo"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Privzeto za zasebni prostor"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimizirano za napravo"</string> + <string name="default_app_others" msgid="7793029848126079876">"Drugo"</string> <string name="default_app_none" msgid="9084592086808194457">"Brez"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(privzeta v sistemu)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Ni aplikacij"</string> diff --git a/PermissionController/res/values-sq/strings.xml b/PermissionController/res/values-sq/strings.xml index 28c843027..cfaa864a8 100644 --- a/PermissionController/res/values-sq/strings.xml +++ b/PermissionController/res/values-sq/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Hapja e lidhjeve"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Të parazgjedhura për punën"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Të parazgjedhurat për hapësirën private"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Optimizuar për pajisjen"</string> + <string name="default_app_others" msgid="7793029848126079876">"Të tjera"</string> <string name="default_app_none" msgid="9084592086808194457">"Asnjë"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Parazgjedhja e sistemit)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Nuk ka aplikacione"</string> diff --git a/PermissionController/res/values-sw/strings.xml b/PermissionController/res/values-sw/strings.xml index aa32dc897..3dedd0126 100644 --- a/PermissionController/res/values-sw/strings.xml +++ b/PermissionController/res/values-sw/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Kufungua viungo"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Programu chaguomsingi kazini"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Programu chaguomsingi za sehemu ya faragha"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Zilizoboreshwa ili kufaa kifaa chako"</string> + <string name="default_app_others" msgid="7793029848126079876">"Nyingine"</string> <string name="default_app_none" msgid="9084592086808194457">"Hakuna"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Programu chaguomsingi ya mfumo)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Hakuna programu"</string> diff --git a/PermissionController/res/values-ta/strings.xml b/PermissionController/res/values-ta/strings.xml index dcf6e7126..fa42187af 100644 --- a/PermissionController/res/values-ta/strings.xml +++ b/PermissionController/res/values-ta/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"இணைப்புகளைத் திறத்தல்"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"பணிக்கான இயல்பு நிலை ஆப்ஸ்"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ரகசிய இடத்திற்கான இயல்பு"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"சாதனத்திற்காக மேம்படுத்தப்பட்டவை"</string> + <string name="default_app_others" msgid="7793029848126079876">"மற்றவை"</string> <string name="default_app_none" msgid="9084592086808194457">"ஏதுமில்லை"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(சிஸ்டத்தின் இயல்புநிலை)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"ஆப்ஸ் இல்லை"</string> @@ -682,7 +680,7 @@ <string name="enhanced_confirmation_dialog_desc" msgid="5921240234843839219">"உங்கள் பாதுகாப்பிற்காக, இந்த அமைப்பு தற்போது இல்லை."</string> <string name="enhanced_confirmation_phone_state_dialog_title" msgid="5054064107559019689">"அழைப்பின்போது செயலை நிறைவுசெய்ய முடியாது"</string> <string name="enhanced_confirmation_phone_state_dialog_desc" msgid="5049619986796367451">"<xliff:g id="SETTING_DESCRIPTION">%1$s</xliff:g>\n\n உங்கள் சாதனத்தையும் தரவையும் பாதுகாப்பதற்காக இந்த அமைப்பு தடுக்கப்பட்டுள்ளது"</string> - <string name="enhanced_confirmation_phone_state_dialog_install_desc_prefix" msgid="7153600694011441796">"புதிய ஆவணத்தில் இருந்து அறியப்படாத ஆப்ஸை நிறுவுமாறு கேட்பதன் மூலம் மோசடி செய்பவர்கள் தீங்கு விளைவிக்கும் ஆப்ஸை நிறுவ முயலலாம்."</string> + <string name="enhanced_confirmation_phone_state_dialog_install_desc_prefix" msgid="7153600694011441796">"புதிய மூலத்தில் இருந்து அறியப்படாத ஆப்ஸை நிறுவுமாறு கேட்பதன் மூலம் மோசடி செய்பவர்கள் தீங்கு விளைவிக்கும் ஆப்ஸை நிறுவ முயலலாம்."</string> <string name="enhanced_confirmation_phone_state_dialog_a11y_desc_prefix" msgid="1086282331085551407">"ஆப்ஸுக்கான அணுகல்தன்மை அம்சங்களை அனுமதிக்குமாறு கேட்பதன் மூலம் மோசடி செய்பவர்கள் உங்கள் சாதனத்தைக் கட்டுப்படுத்த முயலலாம்."</string> <string name="enhanced_confirmation_phone_state_dialog_generic_desc_prefix" msgid="8141411486179553156">"இந்த அமைப்பு மூலம் மோசடி செய்பவர்கள் உங்கள் சாதனத்திற்குத் தீங்கு விளைவிக்க முயலலாம்."</string> <string name="enhanced_confirmation_dialog_title_permission" msgid="2149144789394238266">"<xliff:g id="PERMISSION_NAME">%1$s</xliff:g>க்கான ஆப்ஸ் அணுகல் நிராகரிக்கப்பட்டது"</string> diff --git a/PermissionController/res/values-te/strings.xml b/PermissionController/res/values-te/strings.xml index 8d7d33acc..2122e58a7 100644 --- a/PermissionController/res/values-te/strings.xml +++ b/PermissionController/res/values-te/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"లింక్లను తెరవడం"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"వర్క్ ప్లేస్ కోసం ఆటోమేటిక్"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ఆటోమేటిక్గా ప్రైవేట్ స్పేస్"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"పరికరం కోసం ఆప్టిమైజ్ చేసినవి"</string> + <string name="default_app_others" msgid="7793029848126079876">"ఇతర యాప్లు"</string> <string name="default_app_none" msgid="9084592086808194457">"ఏదీ కాదు"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(సిస్టమ్ ఆటోమేటిక్)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"ఏ యాప్ లేదు"</string> diff --git a/PermissionController/res/values-th/strings.xml b/PermissionController/res/values-th/strings.xml index 1d3821031..02eb8f9de 100644 --- a/PermissionController/res/values-th/strings.xml +++ b/PermissionController/res/values-th/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"การเปิดลิงก์"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"ค่าเริ่มต้นสำหรับงาน"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"ค่าเริ่มต้นสำหรับพื้นที่ส่วนตัว"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"ได้รับการเพิ่มประสิทธิภาพสำหรับอุปกรณ์"</string> + <string name="default_app_others" msgid="7793029848126079876">"อื่นๆ"</string> <string name="default_app_none" msgid="9084592086808194457">"ไม่มี"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(ค่าเริ่มต้นของระบบ)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"ไม่มีแอป"</string> diff --git a/PermissionController/res/values-tl/strings.xml b/PermissionController/res/values-tl/strings.xml index 7bba450be..63c2a120f 100644 --- a/PermissionController/res/values-tl/strings.xml +++ b/PermissionController/res/values-tl/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Pagbubukas ng mga link"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Default para sa trabaho"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Default para sa pribadong space"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Na-optimize para sa device"</string> + <string name="default_app_others" msgid="7793029848126079876">"Iba pa"</string> <string name="default_app_none" msgid="9084592086808194457">"Wala"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Default ng system)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Walang app"</string> diff --git a/PermissionController/res/values-tr/strings.xml b/PermissionController/res/values-tr/strings.xml index 278710a89..d0156068d 100644 --- a/PermissionController/res/values-tr/strings.xml +++ b/PermissionController/res/values-tr/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Bağlantıları açma"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"İş için varsayılan"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Özel alan için varsayılan"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Cihaz için optimize edilenler"</string> + <string name="default_app_others" msgid="7793029848126079876">"Diğer"</string> <string name="default_app_none" msgid="9084592086808194457">"Yok"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Sistem varsayılanı)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Uygulama yok"</string> diff --git a/PermissionController/res/values-uk/strings.xml b/PermissionController/res/values-uk/strings.xml index 8f73e5067..7380d31ed 100644 --- a/PermissionController/res/values-uk/strings.xml +++ b/PermissionController/res/values-uk/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Відкривання посилань"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Для роботи за умовчанням"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"За умовчанням для приватного простору"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Оптимізовано для пристрою"</string> + <string name="default_app_others" msgid="7793029848126079876">"Інші"</string> <string name="default_app_none" msgid="9084592086808194457">"Немає"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(За умовчанням)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Немає додатків"</string> diff --git a/PermissionController/res/values-vi/strings.xml b/PermissionController/res/values-vi/strings.xml index 0e0d61830..eb1354df3 100644 --- a/PermissionController/res/values-vi/strings.xml +++ b/PermissionController/res/values-vi/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Mở đường liên kết"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Ứng dụng mặc định cho công việc"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Ứng dụng mặc định cho không gian riêng tư"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Tối ưu hoá cho thiết bị"</string> + <string name="default_app_others" msgid="7793029848126079876">"Ứng dụng khác"</string> <string name="default_app_none" msgid="9084592086808194457">"Không có"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Ứng dụng mặc định của hệ thống)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Không có ứng dụng nào"</string> diff --git a/PermissionController/res/values-zh-rCN/strings.xml b/PermissionController/res/values-zh-rCN/strings.xml index 5c668001a..b498572ab 100644 --- a/PermissionController/res/values-zh-rCN/strings.xml +++ b/PermissionController/res/values-zh-rCN/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"打开链接"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"默认工作应用"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"私密空间的默认应用"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"针对设备进行了优化"</string> + <string name="default_app_others" msgid="7793029848126079876">"其他"</string> <string name="default_app_none" msgid="9084592086808194457">"无"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(系统默认)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"没有应用"</string> diff --git a/PermissionController/res/values-zh-rHK/strings.xml b/PermissionController/res/values-zh-rHK/strings.xml index c6c3a9a89..86f448e13 100644 --- a/PermissionController/res/values-zh-rHK/strings.xml +++ b/PermissionController/res/values-zh-rHK/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"開啟連結"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"預設用於工作"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"私人空間的預設應用程式"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"已針對你的裝置優化"</string> + <string name="default_app_others" msgid="7793029848126079876">"其他"</string> <string name="default_app_none" msgid="9084592086808194457">"無"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(系統預設)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"沒有應用程式"</string> diff --git a/PermissionController/res/values-zh-rTW/strings.xml b/PermissionController/res/values-zh-rTW/strings.xml index 821dce112..b8cd25891 100644 --- a/PermissionController/res/values-zh-rTW/strings.xml +++ b/PermissionController/res/values-zh-rTW/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"開啟連結"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"預設的工作應用程式"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"私人空間的預設應用程式"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"已針對裝置最佳化"</string> + <string name="default_app_others" msgid="7793029848126079876">"其他"</string> <string name="default_app_none" msgid="9084592086808194457">"無"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(系統預設)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"沒有可用的應用程式"</string> diff --git a/PermissionController/res/values-zu/strings.xml b/PermissionController/res/values-zu/strings.xml index e631a971f..aa2ac6819 100644 --- a/PermissionController/res/values-zu/strings.xml +++ b/PermissionController/res/values-zu/strings.xml @@ -440,10 +440,8 @@ <string name="default_apps_manage_domain_urls" msgid="6775566451561036069">"Ivula amalinki"</string> <string name="default_apps_for_work" msgid="4970308943596201811">"Okuzenzakalelayo kokusebenza"</string> <string name="default_apps_for_private_profile" msgid="2022024112144880785">"Okuzenzakalelayo kwendawo engasese"</string> - <!-- no translation found for default_app_recommended (5669584821778942909) --> - <skip /> - <!-- no translation found for default_app_others (7793029848126079876) --> - <skip /> + <string name="default_app_recommended" msgid="5669584821778942909">"Ilungiselelwe idivayisi"</string> + <string name="default_app_others" msgid="7793029848126079876">"Amanye"</string> <string name="default_app_none" msgid="9084592086808194457">"Lutho"</string> <string name="default_app_system_default" msgid="6218386768175513760">"(Okuzenzakalelayo kwesistimu)"</string> <string name="default_app_no_apps" msgid="115720991680586885">"Azikho izinhlelo zokusebenza"</string> diff --git a/PermissionController/res/values/strings.xml b/PermissionController/res/values/strings.xml index 5714a2460..f5a997674 100644 --- a/PermissionController/res/values/strings.xml +++ b/PermissionController/res/values/strings.xml @@ -1409,9 +1409,7 @@ <!-- Content for dialog shown when the user should confirm an incident / bug report. [CHAR LIMIT=none] --> - <string name="incident_report_dialog_text">"<xliff:g id="app_name" example="Gmail">%1$s</xliff:g> is requesting to upload a bug report from this device taken on <xliff:g id="date" example="December 26, 2018">%2$s</xliff:g> at <xliff:g id="time" example="1:20 PM">%3$s</xliff:g>. Bug reports include personal information about your device or logged by apps, for example, user names, location data, device identifiers, and network information. Only share bug reports with people and apps you trust with this information. - -Allow <xliff:g id="app_name" example="Gmail">%4$s</xliff:g> to upload a bug report?"</string> + <string name="incident_report_dialog_text">"<xliff:g id="app_name" example="Gmail">%1$s</xliff:g> is requesting to upload a bug report from this device taken on <xliff:g id="date" example="December 26, 2018">%2$s</xliff:g> at <xliff:g id="time" example="1:20 PM">%3$s</xliff:g>. Bug reports include personal information about your device or logged by apps, for example, user names, location data, device identifiers, and network information. Only share bug reports with people and apps you trust with this information.\n\nAllow <xliff:g id="app_name" example="Gmail">%4$s</xliff:g> to upload a bug report?"</string> <!-- Content for dialog shown when there was an error parsing the incident / bug report. [CHAR LIMIT=none] --> @@ -2031,17 +2029,15 @@ Allow <xliff:g id="app_name" example="Gmail">%4$s</xliff:g> to upload a bug repo <!--Title for dialog displayed to tell user that settings are blocked due to the phone state (such as being in a call with an unknown number) [CHAR LIMIT=50] --> <string name="enhanced_confirmation_phone_state_dialog_title">Can\u2019t complete action during call</string> <!--Content for dialog displayed to tell user that settings are blocked due to the phone state (such as being in a call with an unknown number) [CHAR LIMIT=NONE] --> - <string name="enhanced_confirmation_phone_state_dialog_desc"><xliff:g id="setting_description" example="allowing apps to install other apps">%1$s</xliff:g>\n\n - This setting is blocked to protect your device and data</string> + <string name="enhanced_confirmation_phone_state_dialog_desc">This setting is blocked to protect your device and data.<xliff:g id="scam_use_setting_description" example="scammers may ask you to allow apps to install other apps">%1$s</xliff:g></string> <!--Content explaining that the "install other apps" setting is blocked due to the phone state in a dialog displayed to the user [CHAR LIMIT=NONE] --> - <string name="enhanced_confirmation_phone_state_dialog_install_desc_prefix">Scammers may try to install harmful apps by asking you to install unknown apps from a new source.</string> + <string name="enhanced_confirmation_phone_state_dialog_install_desc"><xliff:g id="empty_line">\n\n</xliff:g>Scammers may try to install harmful apps by asking you to install unknown apps from a new source.</string> <!--Content explaining that the "enable accessibility service" setting is blocked due to the phone state in a dialog displayed to the user [CHAR LIMIT=NONE] --> - <string name="enhanced_confirmation_phone_state_dialog_a11y_desc_prefix">Scammers may try to take control of your device by asking you to allow accessibility access for an app.</string> - - <!--Content explaining that a generic setting is blocked due to the phone state in a dialog displayed to the user [CHAR LIMIT=NONE] --> - <string name="enhanced_confirmation_phone_state_dialog_generic_desc_prefix">Scammers may attempt to harm your device with this setting.</string> + <string name="enhanced_confirmation_phone_state_dialog_a11y_desc"><xliff:g id="empty_line">\n\n</xliff:g>Scammers may try to take control of your device by asking you to allow accessibility access for an app.</string> + <!--Content explaining that a generic setting is blocked due to the phone state in a dialog displayed to the user. currently empty [CHAR LIMIT=NONE] --> + <string name="enhanced_confirmation_phone_state_dialog_generic_desc" /> <!--Title for dialog displayed to tell user that permissions are blocked by setting restrictions [CHAR LIMIT=50] --> <string name="enhanced_confirmation_dialog_title_permission">App was denied access to <xliff:g id="permission_name" example="contacts">%1$s</xliff:g></string> diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml index 0f9ff7112..4ba524462 100644 --- a/PermissionController/res/xml/roles.xml +++ b/PermissionController/res/xml/roles.xml @@ -902,6 +902,8 @@ <permission name="android.permission.READ_SMS" minSdkVersion="33" /> <permission name="android.permission.READ_PEOPLE_DATA" /> <permission name="android.permission.READ_GLOBAL_APP_SEARCH_DATA" /> + <permission name="android.permission.READ_BLOCKED_NUMBERS" + featureFlag="android.permission.flags.Flags.grantReadBlockedNumbersToSystemUiIntelligence" /> </permissions> </role> diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java index 1b7617b0d..6a7251563 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java @@ -26,7 +26,6 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.SharedLibraryInfo; -import android.content.pm.Signature; import android.content.res.Resources; import android.os.Build; import android.os.UserHandle; @@ -505,8 +504,14 @@ public class Role { && Build.VERSION.SDK_INT <= mMaxSdkVersion; } - public boolean isStatic() { - return mStatic; + /** + * Check whether this role is static, which may change due to bypassing qualification. + * + * @param context the {@code Context} to retrieve system services + * @return whether this role is static + */ + public boolean isStatic(@NonNull Context context) { + return mStatic && !isBypassingQualification(context); } /** @@ -621,6 +626,12 @@ public class Role { return mAllowBypassingQualification; } + private boolean isBypassingQualification(@NonNull Context context) { + RoleManager roleManager = context.getSystemService(RoleManager.class); + return shouldAllowBypassingQualification(context) + && RoleManagerCompat.isBypassingRoleQualification(roleManager); + } + /** * Check whether a package is qualified for this role, i.e. whether it contains all the required * components (plus meeting some other general restrictions). @@ -633,9 +644,7 @@ public class Role { */ public boolean isPackageQualifiedAsUser(@NonNull String packageName, @NonNull UserHandle user, @NonNull Context context) { - RoleManager roleManager = context.getSystemService(RoleManager.class); - if (shouldAllowBypassingQualification(context) - && RoleManagerCompat.isBypassingRoleQualification(roleManager)) { + if (isBypassingQualification(context)) { return true; } @@ -1107,7 +1116,8 @@ public class Role { // all users List<UserHandle> profiles = (crossUserRoleUxBugfixEnabled && getExclusivity() == EXCLUSIVITY_PROFILE_GROUP) - ? UserUtils.getUserProfiles(context, true) : List.of(user); + ? UserUtils.getUserProfiles(user, context, true) + : List.of(user); final int profilesSize = profiles.size(); for (int i = 0; i < profilesSize; i++) { UserHandle profile = profiles.get(i); diff --git a/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java index d00fd47af..1a0c83ab8 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java +++ b/PermissionController/role-controller/java/com/android/role/controller/service/RoleControllerServiceImpl.java @@ -173,7 +173,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { // or fallback holders, if any. currentPackageNames = mUserRoleManager.getRoleHolders(roleName); currentPackageNamesSize = currentPackageNames.size(); - boolean isStaticRole = role.isStatic(); + boolean isStaticRole = role.isStatic(mContext); if (currentPackageNamesSize == 0 || isStaticRole) { List<String> packageNamesToAdd = null; if (addedRoleNames.contains(roleName) || isStaticRole) { diff --git a/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java b/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java index 00c05b17c..41233a23e 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java +++ b/PermissionController/role-controller/java/com/android/role/controller/util/UserUtils.java @@ -139,14 +139,16 @@ public final class UserUtils { /** * Returns all the enabled user profiles on the device * + * @param user the {@link UserHandle} to get profiles for * @param context the {@link Context} * @param excludePrivate {@code true} to exclude private profiles from returned list of users */ @NonNull - public static List<UserHandle> getUserProfiles(@NonNull Context context, - boolean excludePrivate) { - UserManager userManager = context.getSystemService(UserManager.class); - List<UserHandle> profiles = userManager.getUserProfiles(); + public static List<UserHandle> getUserProfiles(@NonNull UserHandle user, + @NonNull Context context, boolean excludePrivate) { + Context userContext = getUserContext(context, user); + UserManager userUserManager = userContext.getSystemService(UserManager.class); + List<UserHandle> profiles = userUserManager.getUserProfiles(); if (!excludePrivate) { return profiles; } @@ -154,7 +156,7 @@ public final class UserUtils { final int profilesSize = profiles.size(); for (int i = 0; i < profilesSize; i++) { UserHandle profile = profiles.get(i); - if (!isPrivateProfile(profile, context)) { + if (!isPrivateProfile(profile, userContext)) { filteredProfiles.add(profile); } } diff --git a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt index d3c7e3a0b..c5191938e 100644 --- a/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt +++ b/PermissionController/src/com/android/permissioncontroller/ecm/EnhancedConfirmationDialogActivity.kt @@ -153,8 +153,8 @@ class EnhancedConfirmationDialogActivity : FragmentActivity() { var message: CharSequence? if (settingType == SettingType.BLOCKED_DUE_TO_PHONE_STATE) { title = settingType.titleRes?.let { context.getString(it) } - val messagePrefix = getPhoneStateMessagePrefix(context, settingIdentifier) - message = settingType.messageRes?.let { context.getString(it, messagePrefix) } + val settingMessage = getPhoneStateSettingMessage(context, settingIdentifier) + message = settingType.messageRes?.let { context.getString(it, settingMessage) } } else { val url = context.getString(R.string.help_url_action_disabled_by_restricted_settings) @@ -165,18 +165,17 @@ class EnhancedConfirmationDialogActivity : FragmentActivity() { return Setting(title, message) } - private fun getPhoneStateMessagePrefix( + private fun getPhoneStateSettingMessage( context: Context, settingsIdentifier: String, ): String { return context.getString( when (settingsIdentifier) { AppOpsManager.OPSTR_BIND_ACCESSIBILITY_SERVICE -> - R.string.enhanced_confirmation_phone_state_dialog_a11y_desc_prefix + R.string.enhanced_confirmation_phone_state_dialog_a11y_desc AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES -> - R.string.enhanced_confirmation_phone_state_dialog_install_desc_prefix - else -> - R.string.enhanced_confirmation_phone_state_dialog_generic_desc_prefix + R.string.enhanced_confirmation_phone_state_dialog_install_desc + else -> R.string.enhanced_confirmation_phone_state_dialog_generic_desc } ) } @@ -278,7 +277,7 @@ class EnhancedConfirmationDialogActivity : FragmentActivity() { return AlertDialog.Builder(dialogActivity) .setView(createDialogView(dialogActivity, title, message)) - .setPositiveButton(R.string.enhanced_confirmation_dialog_ok) { _, _ -> + .setPositiveButton(R.string.dialog_close) { _, _ -> dialogActivity.onDialogResult(DialogResult.Okay) } .create() diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/AppPermissionId.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/AppPermissionId.kt deleted file mode 100644 index 061bcb8a3..000000000 --- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/AppPermissionId.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.android.permissioncontroller.permission.model.livedatatypes.v31 - -import android.os.UserHandle - -/** Identifier for an app permission group combination. */ -data class AppPermissionId( - val packageName: String, - val userHandle: UserHandle, - val permissionGroup: String, -) diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightHistoricalPackageOps.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightHistoricalPackageOps.kt deleted file mode 100644 index 04cc8a796..000000000 --- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightHistoricalPackageOps.kt +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.permissioncontroller.permission.model.livedatatypes.v31 - -import android.app.AppOpsManager.AttributedHistoricalOps -import android.app.AppOpsManager.AttributedOpEntry -import android.app.AppOpsManager.HistoricalOp -import android.app.AppOpsManager.HistoricalPackageOps -import android.app.AppOpsManager.OP_FLAG_SELF -import android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED -import android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY -import android.app.AppOpsManager.OpEventProxyInfo -import android.os.UserHandle -import com.android.permissioncontroller.permission.utils.PermissionMapping.getPlatformPermissionGroupForOp - -/** - * Light version of [HistoricalPackageOps] class, tracking the last permission access for system - * permission groups. - */ -data class LightHistoricalPackageOps( - /** Name of the package. */ - val packageName: String, - /** [UserHandle] running the package. */ - val userHandle: UserHandle, - /** - * Data about permission accesses, one [AppPermissionDiscreteAccesses] for each permission - * group. - */ - // TODO(b/262042582): Consider removing this field and using attributed accesses aggregated over - // attribution tags instead. - val appPermissionDiscreteAccesses: List<AppPermissionDiscreteAccesses>, - /** - * Attributed data about permission accesses, one [AttributedAppPermissionDiscreteAccesses] for - * each permission group. - */ - val attributedAppPermissionDiscreteAccesses: List<AttributedAppPermissionDiscreteAccesses> -) { - constructor( - historicalPackageOps: HistoricalPackageOps, - userHandle: UserHandle, - opNames: Set<String> - ) : this( - historicalPackageOps.packageName, - userHandle, - historicalPackageOps.getAppPermissionDiscreteAccesses(userHandle, opNames), - historicalPackageOps.getAttributedAppPermissionDiscreteAccesses(userHandle, opNames), - ) - - /** Companion object for [LightHistoricalPackageOps]. */ - companion object { - /** String to represent the absence of an attribution tag. */ - const val NO_ATTRIBUTION_TAG = "no_attribution_tag" - /** String to represent the absence of a permission group. */ - private const val NO_PERM_GROUP = "no_perm_group" - private const val DISCRETE_ACCESS_OP_FLAGS = - OP_FLAG_SELF or OP_FLAG_TRUSTED_PROXIED or OP_FLAG_TRUSTED_PROXY - - /** - * Creates a list of [AppPermissionDiscreteAccesses] for the provided package, user and ops. - */ - private fun HistoricalPackageOps.getAppPermissionDiscreteAccesses( - userHandle: UserHandle, - opNames: Set<String> - ): List<AppPermissionDiscreteAccesses> { - val permissionsToOpNames = partitionOpsByPermission(opNames) - val appPermissionDiscreteAccesses = mutableListOf<AppPermissionDiscreteAccesses>() - for (permissionToOpNames in permissionsToOpNames.entries) { - this.getDiscreteAccesses(permissionToOpNames.value)?.let { - appPermissionDiscreteAccesses.add( - AppPermissionDiscreteAccesses( - AppPermissionId(packageName, userHandle, permissionToOpNames.key), - it - ) - ) - } - } - - return appPermissionDiscreteAccesses - } - - /** - * Creates a list of [AttributedAppPermissionDiscreteAccesses] for the provided package, - * user and ops. - */ - private fun HistoricalPackageOps.getAttributedAppPermissionDiscreteAccesses( - userHandle: UserHandle, - opNames: Set<String> - ): List<AttributedAppPermissionDiscreteAccesses> { - val permissionsToOpNames = partitionOpsByPermission(opNames) - val attributedAppPermissionDiscreteAccesses = - mutableMapOf<AppPermissionId, MutableMap<String, List<DiscreteAccess>>>() - - val attributedHistoricalOpsList = mutableListOf<AttributedHistoricalOps>() - for (i in 0 until attributedOpsCount) { - attributedHistoricalOpsList.add(getAttributedOpsAt(i)) - } - - for (permissionToOpNames in permissionsToOpNames.entries) { - attributedHistoricalOpsList.forEach { attributedHistoricalOps -> - attributedHistoricalOps.getDiscreteAccesses(permissionToOpNames.value)?.let { - discAccessData -> - val appPermissionId = - AppPermissionId(packageName, userHandle, permissionToOpNames.key) - if (!attributedAppPermissionDiscreteAccesses.containsKey(appPermissionId)) { - attributedAppPermissionDiscreteAccesses[appPermissionId] = - mutableMapOf() - } - attributedAppPermissionDiscreteAccesses[appPermissionId]?.put( - attributedHistoricalOps.tag ?: NO_ATTRIBUTION_TAG, - discAccessData - ) - } - } - } - - return attributedAppPermissionDiscreteAccesses.map { - AttributedAppPermissionDiscreteAccesses(it.key, it.value) - } - } - - /** - * Retrieves all discrete accesses for the provided op names, if any. - * - * Returns null if there are no accesses. - */ - private fun HistoricalPackageOps.getDiscreteAccesses( - opNames: List<String> - ): List<DiscreteAccess>? { - if (opCount == 0) { - return null - } - - val historicalOps = mutableListOf<HistoricalOp>() - for (opName in opNames) { - getOp(opName)?.let { historicalOps.add(it) } - } - - val discreteAccessList = mutableListOf<DiscreteAccess>() - historicalOps.forEach { - for (i in 0 until it.discreteAccessCount) { - val opEntry: AttributedOpEntry = it.getDiscreteAccessAt(i) - discreteAccessList.add( - DiscreteAccess( - it.opName, - opEntry.getLastAccessTime(DISCRETE_ACCESS_OP_FLAGS), - opEntry.getLastDuration(DISCRETE_ACCESS_OP_FLAGS), - opEntry.getLastProxyInfo(DISCRETE_ACCESS_OP_FLAGS) - ) - ) - } - } - - if (discreteAccessList.isEmpty()) { - return null - } - return discreteAccessList.sortedWith(compareBy { -it.accessTimeMs }) - } - - /** - * Retrieves all discrete accesses for the provided op names, if any. - * - * Returns null if there are no accesses. - */ - private fun AttributedHistoricalOps.getDiscreteAccesses( - opNames: List<String> - ): List<DiscreteAccess>? { - if (opCount == 0) { - return null - } - - val historicalOps = mutableListOf<HistoricalOp>() - for (opName in opNames) { - getOp(opName)?.let { historicalOps.add(it) } - } - - val discreteAccessList = mutableListOf<DiscreteAccess>() - historicalOps.forEach { - for (i in 0 until it.discreteAccessCount) { - val attributedOpEntry: AttributedOpEntry = it.getDiscreteAccessAt(i) - discreteAccessList.add( - DiscreteAccess( - it.opName, - attributedOpEntry.getLastAccessTime(DISCRETE_ACCESS_OP_FLAGS), - attributedOpEntry.getLastDuration(DISCRETE_ACCESS_OP_FLAGS), - attributedOpEntry.getLastProxyInfo(DISCRETE_ACCESS_OP_FLAGS) - ) - ) - } - } - - if (discreteAccessList.isEmpty()) { - return null - } - return discreteAccessList.sortedWith(compareBy { -it.accessTimeMs }) - } - - private fun partitionOpsByPermission(ops: Set<String>): Map<String, List<String>> = - ops.groupBy { getPlatformPermissionGroupForOp(it) ?: NO_PERM_GROUP } - .filter { it.key != NO_PERM_GROUP } - } - - /** - * Data class representing permissions accesses for a particular permission group by a - * particular package and user. - */ - data class AppPermissionDiscreteAccesses( - val appPermissionId: AppPermissionId, - val discreteAccesses: List<DiscreteAccess> - ) - - /** - * Data class representing permissions accesses for a particular permission group by a - * particular package and user, partitioned by attribution tag. - */ - data class AttributedAppPermissionDiscreteAccesses( - val appPermissionId: AppPermissionId, - val attributedDiscreteAccesses: Map<String, List<DiscreteAccess>> - ) - - /** Data class representing a discrete permission access. */ - data class DiscreteAccess( - val opName: String, - val accessTimeMs: Long, - val accessDurationMs: Long, - val proxy: OpEventProxyInfo? - ) -} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightPackageOps.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightPackageOps.kt deleted file mode 100644 index b65fda5ea..000000000 --- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/LightPackageOps.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.permissioncontroller.permission.model.livedatatypes.v31 - -import android.app.AppOpsManager.OP_FLAG_SELF -import android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED -import android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY -import android.app.AppOpsManager.PackageOps -import android.os.UserHandle -import com.android.permissioncontroller.permission.utils.PermissionMapping.getPlatformPermissionGroupForOp - -/** - * Light version of [PackageOps] class, tracking the last permission access for system permission - * groups. - */ -data class LightPackageOps( - /** Name of the package. */ - val packageName: String, - /** [UserHandle] running the package. */ - val userHandle: UserHandle, - /** - * Mapping of permission group name to the last access time of any op backing a permission in - * the group. - */ - val lastPermissionGroupAccessTimesMs: Map<String, Long> -) { - constructor( - ops: Set<String>, - packageOps: PackageOps - ) : this( - packageOps.packageName, - UserHandle.getUserHandleForUid(packageOps.uid), - createLastPermissionGroupAccessTimesMap(ops, packageOps) - ) - - /** Companion object for [LightPackageOps]. */ - companion object { - /** Flags to use for querying an op's last access time. */ - private const val OPS_LAST_ACCESS_FLAGS = - OP_FLAG_SELF or OP_FLAG_TRUSTED_PROXIED or OP_FLAG_TRUSTED_PROXY - - /** Creates a mapping from permission group to the last time it was accessed. */ - private fun createLastPermissionGroupAccessTimesMap( - opNames: Set<String>, - packageOps: PackageOps - ): Map<String, Long> { - val lastAccessTimeMs = mutableMapOf<String, Long>() - // Add keys for all permissions groups covered by the provided ops, regardless of - // whether they have been observed recently. - for (permissionGroup in - opNames.mapNotNull { getPlatformPermissionGroupForOp(it) }.toSet()) { - lastAccessTimeMs[permissionGroup] = -1 - } - - for (opEntry in packageOps.ops) { - val permissionGroupOfOp = getPlatformPermissionGroupForOp(opEntry.opStr) ?: continue - lastAccessTimeMs[permissionGroupOfOp] = - maxOf( - lastAccessTimeMs[permissionGroupOfOp] ?: -1, - opEntry.getLastAccessTime(OPS_LAST_ACCESS_FLAGS) - ) - } - - return lastAccessTimeMs - } - } -} diff --git a/PermissionController/src/com/android/permissioncontroller/role/Role.md b/PermissionController/src/com/android/permissioncontroller/role/Role.md index 255214495..29a184190 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/Role.md +++ b/PermissionController/src/com/android/permissioncontroller/role/Role.md @@ -55,7 +55,13 @@ apps, separated by a colon (`:`) with the package name, for instance receive short text messages, photos, videos, and more". For default apps, this string will appear in the default app detail page as a footer. This attribute is required if the role is `visible`. - `exclusive`: Whether the role is exclusive. If a role is exclusive, at most one application is -allowed to be its holder. +allowed to be its holder. This attribute is being deprecated and `exclusivity` should be used. +- `exclusivity`: Whether the role is exclusive and what type of exclusivity behavior it has. A role +can have exclusivity of `none`, `user`, or `profileGroup`. + - `none`: Role allows multiple holders + - `user`: Role allows at most one holder within each user + - `profileGroup`: (SDK 36+ only, falls back to `user` on lower SDK) Role allows at most one holder +within a profile group (e.g. full user and work profile) - `fallBackToDefaultHolder`: Whether the role should fall back to the default holder. This attribute is optional and defaults to `false`. - `featureFlag`: Optional feature flag for the role be available, as the fully qualified name of diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java index 268633c4f..814a312c6 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppChildFragment.java @@ -16,6 +16,8 @@ package com.android.permissioncontroller.role.ui; +import static com.android.permissioncontroller.PermissionControllerStatsLog.ROLE_SETTINGS_FRAGMENT_ACTION_REPORTED; + import android.app.Activity; import android.app.role.RoleManager; import android.content.Context; @@ -41,6 +43,7 @@ import androidx.preference.TwoStatePreference; import com.android.modules.utils.build.SdkLevel; import com.android.permission.flags.Flags; +import com.android.permissioncontroller.PermissionControllerStatsLog; import com.android.permissioncontroller.R; import com.android.permissioncontroller.permission.utils.Utils; import com.android.permissioncontroller.role.utils.PackageUtils; @@ -48,6 +51,7 @@ import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils; import com.android.permissioncontroller.role.utils.SettingsCompat; import com.android.role.controller.model.Role; import com.android.role.controller.model.Roles; +import com.android.settingslib.utils.applications.AppUtils; import java.util.List; import java.util.Objects; @@ -77,8 +81,8 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat DefaultAppChildFragment.class.getName() + ".preference.OTHER_NFC_SERVICES"; private static final String PREFERENCE_EXTRA_PACKAGE_NAME = DefaultAppChildFragment.class.getName() + ".extra.PACKAGE_NAME"; - private static final String PREFERENCE_EXTRA_USER = DefaultAppChildFragment.class.getName() - + ".extra.USER"; + private static final String PREFERENCE_EXTRA_UID = DefaultAppChildFragment.class.getName() + + ".extra.UID"; @NonNull private String mRoleName; @@ -302,10 +306,13 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat // the `NONE` item passes a null applicationinfo object. NFC uses a different preference // method for adding, and a different onclick method if (applicationInfo != null) { + UserHandle user = UserHandle.getUserHandleForUid(applicationInfo.uid); + roleApplicationPreference.setContentDescription( + AppUtils.getAppContentDescription( + context, applicationInfo.packageName, user.getIdentifier())); Bundle extras = preference.getExtras(); extras.putString(PREFERENCE_EXTRA_PACKAGE_NAME, applicationInfo.packageName); - extras.putParcelable(PREFERENCE_EXTRA_USER, - UserHandle.getUserHandleForUid(applicationInfo.uid)); + extras.putInt(PREFERENCE_EXTRA_UID, applicationInfo.uid); } } else { preference = roleApplicationPreference.asTwoStatePreference(); @@ -348,24 +355,25 @@ public class DefaultAppChildFragment<PF extends PreferenceFragmentCompat } else { String packageName = preference.getExtras().getString(PREFERENCE_EXTRA_PACKAGE_NAME); - UserHandle user = - preference.getExtras().getParcelable(PREFERENCE_EXTRA_USER); + int uid = preference.getExtras().getInt(PREFERENCE_EXTRA_UID); CharSequence confirmationMessage = RoleUiBehaviorUtils.getConfirmationMessage(mRole, packageName, requireContext()); if (confirmationMessage != null) { - DefaultAppConfirmationDialogFragment.show(packageName, user, confirmationMessage, + DefaultAppConfirmationDialogFragment.show(packageName, uid, confirmationMessage, this); } else { - setDefaultApp(packageName, user); + setDefaultApp(packageName, uid); } } return true; } @Override - public void setDefaultApp(@NonNull String packageName, @NonNull UserHandle user) { - mViewModel.setDefaultApp(packageName, user); + public void setDefaultApp(@NonNull String packageName, int uid) { + PermissionControllerStatsLog.write( + ROLE_SETTINGS_FRAGMENT_ACTION_REPORTED, uid, packageName, mRoleName); + mViewModel.setDefaultApp(packageName, UserHandle.getUserHandleForUid(uid)); } private void addNonPaymentNfcServicesPreference(@NonNull PreferenceScreen preferenceScreen, diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppConfirmationDialogFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppConfirmationDialogFragment.java index 5f399a0b8..9a9606291 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppConfirmationDialogFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppConfirmationDialogFragment.java @@ -20,11 +20,9 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.Intent; import android.os.Bundle; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.os.BundleCompat; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; @@ -34,27 +32,27 @@ import androidx.fragment.app.Fragment; public class DefaultAppConfirmationDialogFragment extends DialogFragment { private String mPackageName; - private UserHandle mUser; + private int mUid; private CharSequence mMessage; /** * Create a new instance of this fragment. * * @param packageName the package name of the application - * @param user the user the specified package is running in + * @param uid the UID the specified package is running in * @param message the confirmation message * * @return a new instance of this fragment * - * @see #show(String, UserHandle, CharSequence, Fragment) + * @see #show(String, int, CharSequence, Fragment) */ @NonNull public static DefaultAppConfirmationDialogFragment newInstance(@NonNull String packageName, - @NonNull UserHandle user, @NonNull CharSequence message) { + int uid, @NonNull CharSequence message) { DefaultAppConfirmationDialogFragment fragment = new DefaultAppConfirmationDialogFragment(); Bundle arguments = new Bundle(); arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); - arguments.putParcelable(Intent.EXTRA_USER, user); + arguments.putInt(Intent.EXTRA_UID, uid); arguments.putCharSequence(Intent.EXTRA_TEXT, message); fragment.setArguments(arguments); return fragment; @@ -64,15 +62,15 @@ public class DefaultAppConfirmationDialogFragment extends DialogFragment { * Show a new instance of this fragment. * * @param packageName the package name of the application - * @param user the user the specified package is running in + * @param uid the UID the specified package is running in * @param message the confirmation message * @param fragment the parent fragment * - * @see #newInstance(String, UserHandle, CharSequence) + * @see #newInstance(String, int, CharSequence) */ - public static void show(@NonNull String packageName, @NonNull UserHandle user, + public static void show(@NonNull String packageName, int uid, @NonNull CharSequence message, @NonNull Fragment fragment) { - newInstance(packageName, user, message).show(fragment.getChildFragmentManager(), null); + newInstance(packageName, uid, message).show(fragment.getChildFragmentManager(), null); } @Override @@ -81,7 +79,7 @@ public class DefaultAppConfirmationDialogFragment extends DialogFragment { Bundle arguments = getArguments(); mPackageName = arguments.getString(Intent.EXTRA_PACKAGE_NAME); - mUser = BundleCompat.getParcelable(arguments, Intent.EXTRA_USER, UserHandle.class); + mUid = arguments.getInt(Intent.EXTRA_UID); mMessage = arguments.getCharSequence(Intent.EXTRA_TEXT); } @@ -97,7 +95,7 @@ public class DefaultAppConfirmationDialogFragment extends DialogFragment { private void onOk() { Listener listener = (Listener) getParentFragment(); - listener.setDefaultApp(mPackageName, mUser); + listener.setDefaultApp(mPackageName, mUid); } /** @@ -110,6 +108,6 @@ public class DefaultAppConfirmationDialogFragment extends DialogFragment { * * @param packageName the package name of the application */ - void setDefaultApp(@NonNull String packageName, @NonNull UserHandle user); + void setDefaultApp(@NonNull String packageName, int uid); } } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java index 2a987167e..fd91d0d3b 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/DefaultAppListChildFragment.java @@ -40,10 +40,12 @@ import androidx.preference.PreferenceScreen; import com.android.modules.utils.build.SdkLevel; import com.android.permissioncontroller.R; import com.android.permissioncontroller.permission.utils.Utils; +import com.android.permissioncontroller.role.UserPackage; import com.android.permissioncontroller.role.utils.PackageUtils; import com.android.permissioncontroller.role.utils.RoleUiBehaviorUtils; import com.android.role.controller.model.Role; import com.android.role.controller.model.Roles; +import com.android.settingslib.utils.applications.AppUtils; import java.util.List; @@ -241,10 +243,16 @@ public class DefaultAppListChildFragment<PF extends PreferenceFragmentCompat if (holderApplicationInfos.isEmpty()) { preference.setIcon(null); preference.setSummary(R.string.default_app_none); + rolePreference.setSummaryContentDescription(null); } else { ApplicationInfo holderApplicationInfo = holderApplicationInfos.get(0); preference.setIcon(Utils.getBadgedIcon(context, holderApplicationInfo)); preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context)); + UserPackage userPackage = UserPackage.from(holderApplicationInfo); + rolePreference.setSummaryContentDescription( + AppUtils.getAppContentDescription(context, + userPackage.packageName, + userPackage.user.getIdentifier())); } RoleUiBehaviorUtils.preparePreferenceAsUser(role, holderApplicationInfos, rolePreference, user, context); diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java index 4731c8b0f..89a17004b 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RequestRoleFragment.java @@ -59,6 +59,7 @@ import com.android.permissioncontroller.role.utils.UiUtils; import com.android.permissioncontroller.role.utils.UserUtils; import com.android.role.controller.model.Role; import com.android.role.controller.model.Roles; +import com.android.settingslib.utils.applications.AppUtils; import java.util.ArrayList; import java.util.List; @@ -698,6 +699,7 @@ public class RequestRoleFragment extends DialogFragment { Drawable icon; String title; String subtitle; + String contentDescription; if (applicationItem == null) { applicationInfo = null; restricted = false; @@ -706,6 +708,7 @@ public class RequestRoleFragment extends DialogFragment { title = context.getString(R.string.default_app_none); subtitle = mHolderUserPackage == null ? context.getString( R.string.request_role_current_default) : null; + contentDescription = null; } else { applicationInfo = applicationItem.getApplicationInfo(); UserPackage userPackage = UserPackage.from(applicationInfo); @@ -717,14 +720,18 @@ public class RequestRoleFragment extends DialogFragment { subtitle = applicationItem.isHolderApplication() ? context.getString(R.string.request_role_current_default) : checked ? context.getString(mRole.getRequestDescriptionResource()) : null; + contentDescription = AppUtils.getAppContentDescription(context, + userPackage.packageName, userPackage.user.getIdentifier()); } boolean enabled = isEnabled(position); UiUtils.setViewTreeEnabled(view, enabled && !restricted); view.setEnabled(enabled); view.setChecked(checked); + holder.iconImage.setImageDrawable(icon); holder.titleText.setText(title); + holder.titleText.setContentDescription(contentDescription); holder.subtitleText.setVisibility(!TextUtils.isEmpty(subtitle) ? View.VISIBLE : View.GONE); holder.subtitleText.setText(subtitle); diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java index 1d3e32c9c..3336aad50 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RoleApplicationPreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.TwoStatePreference; /** @@ -29,4 +30,9 @@ public interface RoleApplicationPreference extends RestrictionAwarePreference { */ @NonNull TwoStatePreference asTwoStatePreference(); + + /** + * Sets the preference's content description. + */ + void setContentDescription(@Nullable String contentDescription); } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java index bbc123cfe..feafb0ae5 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/RolePreference.java @@ -17,6 +17,7 @@ package com.android.permissioncontroller.role.ui; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.Preference; /** @@ -28,4 +29,9 @@ public interface RolePreference extends TwoTargetPreference, RestrictionAwarePre */ @NonNull Preference asPreference(); + + /** + * Sets the preference's summary content description. + */ + void setSummaryContentDescription(@Nullable String summaryContentDescription); } 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 764c07497..f0a27284d 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRadioPreference.java @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; import android.content.Intent; import android.widget.RadioButton; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -30,10 +31,15 @@ import com.android.permissioncontroller.R; import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; +import java.util.Objects; + /** Preference used to represent apps that can be picked as a default app. */ public class AutoRadioPreference extends TwoStatePreference implements RoleApplicationPreference { + @Nullable + private String mContentDescription; + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = new RestrictionAwarePreferenceMixin(this); @@ -56,10 +62,21 @@ public class AutoRadioPreference extends TwoStatePreference implements RadioButton radioButton = (RadioButton) holder.findViewById(R.id.radio_button); radioButton.setChecked(isChecked()); + TextView titleText = (TextView) holder.findViewById(android.R.id.title); + titleText.setContentDescription(mContentDescription); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } @Override + public void setContentDescription(@Nullable String contentDescription) { + if (!Objects.equals(mContentDescription, contentDescription)) { + mContentDescription = contentDescription; + notifyChanged(); + } + } + + @Override public void setRestrictionIntent(@Nullable Intent restrictionIntent) { mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } 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 15fd117d1..28dfc67f9 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoRolePreference.java @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; import android.content.Intent; import android.util.AttributeSet; +import android.widget.TextView; import androidx.annotation.AttrRes; import androidx.annotation.NonNull; @@ -31,12 +32,17 @@ import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RolePreference; import com.android.permissioncontroller.role.ui.TwoTargetPreference; +import java.util.Objects; + /** * Preference for use in auto lists. Extends {@link TwoTargetPreference} in order to make sure of * shared logic between phone and auto settings UI. */ public class AutoRolePreference extends Preference implements RolePreference { + @Nullable + private String mSummaryContentDescription; + private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = new RestrictionAwarePreferenceMixin(this); @@ -62,6 +68,14 @@ public class AutoRolePreference extends Preference implements RolePreference { public void setOnSecondTargetClickListener(@Nullable OnSecondTargetClickListener listener) {} @Override + public void setSummaryContentDescription(@Nullable String summaryContentDescription) { + if (!Objects.equals(mSummaryContentDescription, summaryContentDescription)) { + mSummaryContentDescription = summaryContentDescription; + notifyChanged(); + } + } + + @Override public void setRestrictionIntent(@Nullable Intent restrictionIntent) { mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @@ -70,6 +84,9 @@ public class AutoRolePreference extends Preference implements RolePreference { public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); + TextView summaryText = (TextView) holder.findViewById(android.R.id.summary); + summaryText.setContentDescription(mSummaryContentDescription); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } 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 bfb2b5d1d..e7279278c 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/auto/AutoSwitchPreference.java @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui.auto; import android.content.Context; import android.content.Intent; import android.util.AttributeSet; +import android.widget.TextView; import androidx.annotation.AttrRes; import androidx.annotation.NonNull; @@ -30,12 +31,16 @@ import androidx.preference.SwitchPreference; import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; +import java.util.Objects; + /** * Role application preference represented as a switch. */ public class AutoSwitchPreference extends SwitchPreference implements RoleApplicationPreference { + @Nullable + private String mContentDescription; private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = new RestrictionAwarePreferenceMixin(this); @@ -58,6 +63,14 @@ public class AutoSwitchPreference extends SwitchPreference } @Override + public void setContentDescription(@Nullable String contentDescription) { + if (!Objects.equals(mContentDescription, contentDescription)) { + mContentDescription = contentDescription; + notifyChanged(); + } + } + + @Override public void setRestrictionIntent(@Nullable Intent restrictionIntent) { mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @@ -66,6 +79,9 @@ public class AutoSwitchPreference extends SwitchPreference public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); + TextView titleText = (TextView) holder.findViewById(android.R.id.title); + titleText.setContentDescription(mContentDescription); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/v35/WalletRoleUiBehavior.java b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/v35/WalletRoleUiBehavior.java index f1754dde9..eb1dbb5ef 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/v35/WalletRoleUiBehavior.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/behavior/v35/WalletRoleUiBehavior.java @@ -22,6 +22,8 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.nfc.cardemulation.ApduServiceInfo; import android.nfc.cardemulation.CardEmulation; @@ -39,6 +41,8 @@ import androidx.annotation.RequiresApi; import androidx.core.util.Pair; import androidx.preference.Preference; +import com.android.launcher3.icons.IconFactory; +import com.android.permissioncontroller.role.ui.RequestRoleItemView; import com.android.permissioncontroller.role.ui.TwoTargetPreference; import com.android.permissioncontroller.role.ui.behavior.RoleUiBehavior; import com.android.role.controller.model.Role; @@ -70,6 +74,21 @@ public class WalletRoleUiBehavior implements RoleUiBehavior { } @Override + public void prepareRequestRoleItemViewAsUser(@NonNull Role role, + @NonNull RequestRoleItemView itemView, @NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, @NonNull Context context) { + if (isSystemApplication(applicationInfo)) { + Pair<Drawable, CharSequence> bannerAndLabel = getLabelAndIconIfItExists( + applicationInfo, user, context); + + if (bannerAndLabel != null) { + itemView.getIconImageView().setImageDrawable(bannerAndLabel.first); + itemView.getTitleTextView().setText(bannerAndLabel.second); + } + } + } + + @Override public void prepareApplicationPreferenceAsUser(@NonNull Role role, @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user, @NonNull Context context) { @@ -81,21 +100,8 @@ public class WalletRoleUiBehavior implements RoleUiBehavior { @NonNull ApplicationInfo applicationInfo, boolean setTitle, @NonNull UserHandle user, @NonNull Context context) { if (isSystemApplication(applicationInfo)) { - List<ApduServiceInfo> serviceInfos = getNfcServicesForPackage( - applicationInfo.packageName, user, context); - - Pair<Drawable, CharSequence> bannerAndLabel = null; - // If the flag is enabled , attempt to fetch it from property - if (Flags.walletRoleIconPropertyEnabled()) { - bannerAndLabel = - getBannerAndLabelFromPackageProperty(context, user, - applicationInfo.packageName); - } - // If it's null, indicating that the property is not set, perform a legacy icon lookup. - if (bannerAndLabel == null) { - bannerAndLabel = - getNonPaymentServiceBannerAndLabelIfExists(serviceInfos, user, context); - } + Pair<Drawable, CharSequence> bannerAndLabel = getLabelAndIconIfItExists( + applicationInfo, user, context); if (bannerAndLabel != null) { preference.setIcon(bannerAndLabel.first); if (setTitle) { @@ -107,6 +113,26 @@ public class WalletRoleUiBehavior implements RoleUiBehavior { } } + @Nullable + private Pair<Drawable, CharSequence> getLabelAndIconIfItExists( + @NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, + @NonNull Context context) { + Pair<Drawable, CharSequence> result = null; + // If the flag is enabled , attempt to fetch it from property + if (Flags.walletRoleIconPropertyEnabled()) { + result = getBannerAndLabelFromPackageProperty(context, user, + applicationInfo.packageName); + } + if (result != null) { + return result; + } + List<ApduServiceInfo> serviceInfos = getNfcServicesForPackage( + applicationInfo.packageName, user, context); + // If it's null, indicating that the property is not set, perform a legacy icon lookup. + return getNonPaymentServiceBannerAndLabelIfExists(serviceInfos, user, context); + } + @Nullable private Pair<Drawable, CharSequence> getBannerAndLabelFromPackageProperty( @@ -122,7 +148,7 @@ public class WalletRoleUiBehavior implements RoleUiBehavior { PackageManager.Property iconProperty = packageManager.getProperty( ApduServiceInfo.PROPERTY_WALLET_PREFERRED_BANNER_AND_LABEL, componentName); if (iconProperty.isBoolean() && iconProperty.getBoolean()) { - return loadBannerAndLabel(serviceInfo, packageManager); + return loadBannerAndLabel(serviceInfo, packageManager, context, user); } } catch (PackageManager.NameNotFoundException e) { continue; @@ -186,7 +212,8 @@ public class WalletRoleUiBehavior implements RoleUiBehavior { for (int i = 0; i < apduServiceInfoSize; i++) { ApduServiceInfo serviceInfo = apduServiceInfos.get(i); if (serviceInfo.getAids().isEmpty()) { - bannerAndLabel = loadBannerAndLabel(serviceInfo, userPackageManager); + bannerAndLabel = loadBannerAndLabel(serviceInfo, userPackageManager, context, + user); if (bannerAndLabel != null) { return bannerAndLabel; } @@ -197,7 +224,8 @@ public class WalletRoleUiBehavior implements RoleUiBehavior { String aid = aids.get(j); String category = serviceInfo.getCategoryForAid(aid); if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) { - bannerAndLabel = loadBannerAndLabel(serviceInfo, userPackageManager); + bannerAndLabel = loadBannerAndLabel(serviceInfo, userPackageManager, + context, user); if (bannerAndLabel != null) { return bannerAndLabel; } @@ -210,8 +238,20 @@ public class WalletRoleUiBehavior implements RoleUiBehavior { @Nullable private Pair<Drawable, CharSequence> loadBannerAndLabel(@NonNull ApduServiceInfo info, - @NonNull PackageManager userPackageManager) { + @NonNull PackageManager userPackageManager, @NonNull Context context, + @NonNull UserHandle user) { Drawable drawable = info.loadBanner(userPackageManager); + if (drawable != null) { + try (IconFactory factory = IconFactory.obtain(context)) { + Bitmap badged = + factory.createBadgedIconBitmap(drawable, user, + false).icon; + if (badged != null) { + drawable = new BitmapDrawable(context.getResources(), badged); + } + } + } + CharSequence label = info.loadLabel(userPackageManager); if (drawable != null && !TextUtils.isEmpty(label)) { return new Pair<>(drawable, label); 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 67f04051c..2a943d3d7 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRadioPreference.java @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui.handheld; import android.content.Context; import android.content.Intent; import android.util.AttributeSet; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -28,12 +29,17 @@ import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; import com.android.settingslib.widget.SelectorWithWidgetPreference; +import java.util.Objects; + /** * Preference used to represent apps that can be picked as a default app. */ public class HandheldRadioPreference extends SelectorWithWidgetPreference implements RoleApplicationPreference { + @Nullable + private String mContentDescription; + private final RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = new RestrictionAwarePreferenceMixin(this); @@ -56,6 +62,14 @@ public class HandheldRadioPreference extends SelectorWithWidgetPreference implem } @Override + public void setContentDescription(@Nullable String contentDescription) { + if (!Objects.equals(mContentDescription, contentDescription)) { + mContentDescription = contentDescription; + notifyChanged(); + } + } + + @Override public void setRestrictionIntent(@Nullable Intent restrictionIntent) { mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @@ -64,6 +78,9 @@ public class HandheldRadioPreference extends SelectorWithWidgetPreference implem public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); + TextView titleText = (TextView) holder.findViewById(android.R.id.title); + titleText.setContentDescription(mContentDescription); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } 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 3d09f0b46..46bf3b173 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/handheld/HandheldRolePreference.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.util.AttributeSet; import android.view.View; +import android.widget.TextView; import androidx.annotation.AttrRes; import androidx.annotation.NonNull; @@ -33,6 +34,8 @@ import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RolePreference; import com.android.settingslib.widget.TwoTargetPreference; +import java.util.Objects; + /** * {@link Preference} with a settings button. * @@ -45,6 +48,9 @@ public class HandheldRolePreference extends TwoTargetPreference implements RoleP new RestrictionAwarePreferenceMixin(this); @Nullable + private String mSummaryContentDescription; + + @Nullable private OnSecondTargetClickListener mOnSecondTargetClickListener; public HandheldRolePreference(@NonNull Context context, @Nullable AttributeSet attrs, @@ -94,6 +100,14 @@ public class HandheldRolePreference extends TwoTargetPreference implements RoleP } @Override + public void setSummaryContentDescription(@Nullable String summaryContentDescription) { + if (!Objects.equals(mSummaryContentDescription, summaryContentDescription)) { + mSummaryContentDescription = summaryContentDescription; + notifyChanged(); + } + } + + @Override public void setRestrictionIntent(@Nullable Intent restrictionIntent) { mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @@ -114,6 +128,9 @@ public class HandheldRolePreference extends TwoTargetPreference implements RoleP // Make the settings button enabled even if the preference itself is disabled. settingsButton.setEnabled(true); + TextView summaryText = (TextView) holder.findViewById(android.R.id.summary); + summaryText.setContentDescription(mSummaryContentDescription); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } 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 ded6d5cb5..a801c2182 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 @@ -19,6 +19,7 @@ package com.android.permissioncontroller.role.ui.specialappaccess.handheld; import android.content.Context; import android.content.Intent; import android.util.AttributeSet; +import android.widget.TextView; import androidx.annotation.AttrRes; import androidx.annotation.NonNull; @@ -30,10 +31,14 @@ import com.android.permissioncontroller.role.ui.RestrictionAwarePreferenceMixin; import com.android.permissioncontroller.role.ui.RoleApplicationPreference; import com.android.settingslib.widget.AppSwitchPreference; +import java.util.Objects; + /** {@link AppSwitchPreference} that is a role application preference. */ public class HandheldSwitchPreference extends AppSwitchPreference implements RoleApplicationPreference { + @Nullable + private String mContentDescription; private RestrictionAwarePreferenceMixin mRestrictionAwarePreferenceMixin = new RestrictionAwarePreferenceMixin(this); @@ -56,6 +61,14 @@ public class HandheldSwitchPreference extends AppSwitchPreference } @Override + public void setContentDescription(@Nullable String contentDescription) { + if (!Objects.equals(mContentDescription, contentDescription)) { + mContentDescription = contentDescription; + notifyChanged(); + } + } + + @Override public void setRestrictionIntent(@Nullable Intent restrictionIntent) { mRestrictionAwarePreferenceMixin.setRestrictionIntent(restrictionIntent); } @@ -64,6 +77,9 @@ public class HandheldSwitchPreference extends AppSwitchPreference public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); + TextView titleText = (TextView) holder.findViewById(android.R.id.title); + titleText.setContentDescription(mContentDescription); + mRestrictionAwarePreferenceMixin.onAfterBindViewHolder(holder); } 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 6cd52f576..cb12bf70a 100644 --- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt +++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRoleApplicationPreference.kt @@ -18,6 +18,7 @@ package com.android.permissioncontroller.role.ui.wear import android.content.Context import android.content.Intent +import androidx.preference.PreferenceViewHolder import androidx.preference.TwoStatePreference import com.android.permissioncontroller.role.ui.RoleApplicationPreference @@ -30,7 +31,8 @@ class WearRoleApplicationPreference( defaultLabel: String, val checked: Boolean, val onDefaultCheckChanged: (Boolean) -> Unit = {}, - private var restrictionIntent: Intent? = null + private var restrictionIntent: Intent? = null, + private var contentDescription: String? = null, ) : TwoStatePreference(context), RoleApplicationPreference { init { title = defaultLabel @@ -39,10 +41,22 @@ class WearRoleApplicationPreference( fun getOnCheckChanged(): (Boolean) -> Unit = restrictionIntent?.let { { _ -> context.startActivity(it) } } ?: onDefaultCheckChanged + override fun setContentDescription(contentDescription: String?) { + if (this.contentDescription != contentDescription) { + this.contentDescription = contentDescription + notifyChanged() + } + } + override fun setRestrictionIntent(restrictionIntent: Intent?) { this.restrictionIntent = restrictionIntent isEnabled = restrictionIntent == null } override fun asTwoStatePreference(): TwoStatePreference = this + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + holder.findViewById(android.R.id.title)?.let { it.contentDescription = contentDescription } + } } 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 43acf4293..670c136ea 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.content.Context import android.content.Intent import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder import com.android.permissioncontroller.role.ui.RolePreference import com.android.permissioncontroller.role.ui.TwoTargetPreference.OnSecondTargetClickListener import com.android.settingslib.widget.TwoTargetPreference @@ -28,13 +29,21 @@ class WearRolePreference( context: Context, val label: String, val onDefaultClicked: () -> Unit = {}, - private var restrictionIntent: Intent? = null + private var restrictionIntent: Intent? = null, + private var summaryContentDescription: String? = null, ) : TwoTargetPreference(context), RolePreference { override fun setOnSecondTargetClickListener(listener: OnSecondTargetClickListener?) { // no-op } + override fun setSummaryContentDescription(summaryContentDescription: String?) { + if (this.summaryContentDescription != summaryContentDescription) { + this.summaryContentDescription = summaryContentDescription + notifyChanged() + } + } + override fun setRestrictionIntent(restrictionIntent: Intent?) { this.restrictionIntent = restrictionIntent setEnabled(restrictionIntent == null) @@ -42,6 +51,14 @@ class WearRolePreference( override fun asPreference(): Preference = this + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + holder.findViewById(android.R.id.summary)?.let { + it.contentDescription = summaryContentDescription + } + } + fun getOnClicked(): () -> Unit = restrictionIntent?.let { { context.startActivity(it) } } ?: onDefaultClicked } diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt index b5a66da06..d29b0aa3e 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/SafetyCenterFragment.kt @@ -61,7 +61,6 @@ abstract class SafetyCenterFragment : SettingsBasePreferenceFragment() { } else { super.onCreateAdapter(preferenceScreen) } - /* By default, the PreferenceGroupAdapter does setHasStableIds(true). Since each Preference * is internally allocated with an auto-incremented ID, it does not allow us to gracefully * update only changed preferences based on SafetyPreferenceComparisonCallback. In order to @@ -77,10 +76,15 @@ abstract class SafetyCenterFragment : SettingsBasePreferenceFragment() { .split(",") safetyCenterSessionId = requireArguments().getLong(EXTRA_SESSION_ID, INVALID_SESSION_ID) + val activity = requireActivity() safetyCenterViewModel = ViewModelProvider( - requireActivity(), - LiveSafetyCenterViewModelFactory(requireActivity().getApplication()), + activity, + LiveSafetyCenterViewModelFactory( + activity.application, + activity.taskId, + sameTaskSourceIds, + ), ) .get(SafetyCenterViewModel::class.java) safetyCenterViewModel.safetyCenterUiLiveData.observe(this) { uiData: SafetyCenterUiData? -> @@ -91,8 +95,7 @@ abstract class SafetyCenterFragment : SettingsBasePreferenceFragment() { displayErrorDetails(errorDetails) } - val safetyCenterIntent: ParsedSafetyCenterIntent = - requireActivity().intent.toSafetyCenterIntent() + val safetyCenterIntent: ParsedSafetyCenterIntent = activity.intent.toSafetyCenterIntent() val isQsFragment = getArguments()?.getBoolean(QUICK_SETTINGS_SAFETY_CENTER_FRAGMENT, false) ?: false collapsableIssuesCardHelper = diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/package-info.java b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/IssueUiData.kt index b724ba43f..e260bb917 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/v31/package-info.java +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/IssueUiData.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,5 +14,14 @@ * limitations under the License. */ -@androidx.annotation.RequiresApi(android.os.Build.VERSION_CODES.S) -package com.android.permissioncontroller.permission.model.livedatatypes.v31; +package com.android.permissioncontroller.safetycenter.ui.model + +import android.safetycenter.SafetyCenterIssue + +/** UI model representation of [SafetyCenterIssue] */ +data class IssueUiData( + val issue: SafetyCenterIssue, + val isDismissed: Boolean, + val resolvedIssueActionId: String? = null, + val launchTaskId: Int? = null, +) diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt index 4ddcf1c3d..0b976f49d 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/LiveSafetyCenterViewModel.kt @@ -43,11 +43,16 @@ import com.android.safetycenter.internaldata.SafetyCenterIds /* A SafetyCenterViewModel that talks to the real backing service for Safety Center. */ @RequiresApi(Build.VERSION_CODES.TIRAMISU) -class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { +class LiveSafetyCenterViewModel( + app: Application, + private val taskId: Int, + private val sameTaskSourceIds: List<String>, +) : SafetyCenterViewModel(app) { private val TAG: String = LiveSafetyCenterViewModel::class.java.simpleName override val statusUiLiveData: LiveData<StatusUiData> get() = safetyCenterUiLiveData.map { StatusUiData(it.safetyCenterData) } + override val safetyCenterUiLiveData: LiveData<SafetyCenterUiData> by this::_safetyCenterLiveData override val errorLiveData: LiveData<SafetyCenterErrorDetails> by this::_errorLiveData @@ -65,7 +70,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { private val safetyCenterManager = app.getSystemService(SafetyCenterManager::class.java)!! override fun getCurrentSafetyCenterDataAsUiData(): SafetyCenterUiData = - SafetyCenterUiData(safetyCenterManager.safetyCenterData) + uiData(safetyCenterManager.safetyCenterData) override fun dismissIssue(issue: SafetyCenterIssue) { safetyCenterManager.dismissSafetyCenterIssue(issue.id) @@ -74,7 +79,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { override fun executeIssueAction( issue: SafetyCenterIssue, action: SafetyCenterIssue.Action, - launchTaskId: Int? + launchTaskId: Int?, ) { val issueId = if (launchTaskId != null) { @@ -107,9 +112,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { override fun navigateToSafetyCenter(context: Context, navigationSource: NavigationSource?) { val intent = Intent(ACTION_SAFETY_CENTER) - if (navigationSource != null) { - navigationSource.addToIntent(intent) - } + navigationSource?.addToIntent(intent) context.startActivity(intent) } @@ -132,7 +135,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { } else { safetyCenterManager.refreshSafetySources( SafetyCenterManager.REFRESH_REASON_PAGE_OPEN, - safetySourceIds + safetySourceIds, ) } } @@ -174,7 +177,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { override fun onActive() { safetyCenterManager.addOnSafetyCenterDataChangedListener( getMainExecutor(app.applicationContext), - this + this, ) super.onActive() } @@ -209,7 +212,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { Log.d( TAG, "Received SafetyCenterData while issue resolution animations" + - " occurring. Will update UI with new data soon." + " occurring. Will update UI with new data soon.", ) return } @@ -254,7 +257,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { private fun isCurrentlyScanning(): Boolean = value?.safetyCenterData?.isScanning() ?: false private fun sendNextData() { - value = SafetyCenterUiData(safetyCenterDataQueue.removeFirst()) + value = uiData(safetyCenterDataQueue.removeFirst()) } private fun skipNextData() = safetyCenterDataQueue.removeFirst() @@ -270,7 +273,7 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { // The current SafetyCenterData still contains the resolved SafetyCenterIssue objects. // Send it with the resolved IDs so the UI can generate the correct preferences and // trigger the right animations for issue resolution. - value = SafetyCenterUiData(currentData, currentResolvedIssues) + value = uiData(currentData, currentResolvedIssues) } @MainThread @@ -279,6 +282,11 @@ class LiveSafetyCenterViewModel(app: Application) : SafetyCenterViewModel(app) { maybeProcessDataToNextResolvedIssues() } } + + private fun uiData( + safetyCenterData: SafetyCenterData, + resolvedIssues: Map<IssueId, ActionId> = emptyMap(), + ) = SafetyCenterUiData(safetyCenterData, taskId, sameTaskSourceIds, resolvedIssues) } /** Returns inflight issues pending resolution */ @@ -309,8 +317,15 @@ private val SafetyCenterData.allResolvableIssues: Sequence<SafetyCenterIssue> } @RequiresApi(Build.VERSION_CODES.TIRAMISU) -class LiveSafetyCenterViewModelFactory(private val app: Application) : ViewModelProvider.Factory { +class LiveSafetyCenterViewModelFactory +@JvmOverloads +constructor( + private val app: Application, + private val taskId: Int = 0, + private val sameTaskSourceIds: List<String> = emptyList(), +) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { - @Suppress("UNCHECKED_CAST") return LiveSafetyCenterViewModel(app) as T + @Suppress("UNCHECKED_CAST") + return LiveSafetyCenterViewModel(app, taskId, sameTaskSourceIds) as T } } diff --git a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt index 69a315f08..d8aadae2f 100644 --- a/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt +++ b/PermissionController/src/com/android/permissioncontroller/safetycenter/ui/model/SafetyCenterUiData.kt @@ -29,11 +29,21 @@ import com.android.safetycenter.internaldata.SafetyCenterIds import com.android.safetycenter.internaldata.SafetyCenterIssueKey /** UI model representation of Safety Center Data */ +@RequiresApi(TIRAMISU) data class SafetyCenterUiData( val safetyCenterData: SafetyCenterData, - val resolvedIssues: Map<IssueId, ActionId> = emptyMap() + private val taskId: Int, + private val sameTaskSourceIds: List<String>, + val resolvedIssues: Map<IssueId, ActionId> = emptyMap(), ) { - @RequiresApi(TIRAMISU) + + val issueUiDatas: List<IssueUiData> by + lazy(LazyThreadSafetyMode.NONE) { + safetyCenterData.issues.map { + IssueUiData(it, false, resolvedIssues[it.id], getLaunchTaskIdForIssue(it)) + } + } + fun getMatchingIssue(issueKey: SafetyCenterIssueKey): SafetyCenterIssue? { return safetyCenterData.issues.find { SafetyCenterIds.issueIdFromString(it.id).safetyCenterIssueKey == issueKey @@ -67,7 +77,7 @@ data class SafetyCenterUiData( @RequiresApi(UPSIDE_DOWN_CAKE) private fun selectMatchingIssuesForGroup( groupId: String, - issues: List<SafetyCenterIssue> + issues: List<SafetyCenterIssue>, ): List<SafetyCenterIssue> { val issuesToGroups = safetyCenterData.extras.getBundle(ISSUES_TO_GROUPS_BUNDLE_KEY) return issues.filter { @@ -84,4 +94,12 @@ data class SafetyCenterUiData( @RequiresApi(UPSIDE_DOWN_CAKE) fun SafetyCenterData.visibleDismissedIssues() = dismissedIssues.filter { it.severityLevel > ISSUE_SEVERITY_LEVEL_OK } + + private fun getLaunchTaskIdForIssue(issue: SafetyCenterIssue): Int? { + val sourceId: String = + SafetyCenterIds.issueIdFromString(issue.id) + .getSafetyCenterIssueKey() + .getSafetySourceId() + return if (sameTaskSourceIds.contains(sourceId)) taskId else null + } } diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/AdminRestrictedPermissionsUtilsTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/AdminRestrictedPermissionsUtilsTest.kt index 2a60e1325..35543b6f1 100644 --- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/AdminRestrictedPermissionsUtilsTest.kt +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/AdminRestrictedPermissionsUtilsTest.kt @@ -19,12 +19,14 @@ package com.android.permissioncontroller.tests.mocking.permission.utils import android.app.admin.DevicePolicyManager import android.content.Context import android.health.connect.HealthPermissions +import android.os.Build import android.permission.flags.Flags import android.platform.test.annotations.AsbSecurityTest import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.DeviceFlagsValueProvider import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SdkSuppress import com.android.modules.utils.build.SdkLevel import com.android.permissioncontroller.permission.utils.v31.AdminRestrictedPermissionsUtils import org.junit.Assert.assertEquals @@ -74,12 +76,12 @@ object AdminRestrictedPermissionsUtilsTest { companion object { /** - * Returns a list of arrays containing the following values: - * 0. Permission name (String) - * 1. Permission group name (String) - * 2. Can admin grant sensors permissions (Boolean) - * 3. Expected return from mayAdminGrantPermission method (Boolean) - */ + * Returns a list of arrays containing the following values: + * 0. Permission name (String) + * 1. Permission group name (String) + * 2. Can admin grant sensors permissions (Boolean) + * 3. Expected return from mayAdminGrantPermission method (Boolean) + */ @JvmStatic @Parameterized.Parameters(name = "{index}: validate({0}, {1}, {3}) = {4}") fun getParameters(): List<Array<out Any?>> { @@ -109,6 +111,7 @@ object AdminRestrictedPermissionsUtilsTest { class AdminRestrictedPermissionsUtilsSingleTest { @Test + @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA) @RequiresFlagsEnabled(Flags.FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED) fun addAdminRestrictedPermission_addsPermissionToRestrictedList() { var canGrant = diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetycenter/ui/model/SafetyCenterUiDataTest.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetycenter/ui/model/SafetyCenterUiDataTest.kt index ca0392716..e53fabc90 100644 --- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetycenter/ui/model/SafetyCenterUiDataTest.kt +++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/safetycenter/ui/model/SafetyCenterUiDataTest.kt @@ -18,6 +18,7 @@ package com.android.permissioncontroller.tests.mocking.safetycenter.ui.model import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE import android.os.Bundle +import android.os.UserHandle import android.safetycenter.SafetyCenterData import android.safetycenter.SafetyCenterEntryGroup import android.safetycenter.SafetyCenterEntryOrGroup @@ -28,8 +29,14 @@ import android.safetycenter.SafetyCenterIssue.ISSUE_SEVERITY_LEVEL_RECOMMENDATIO import android.safetycenter.SafetyCenterStatus import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SdkSuppress +import com.android.permissioncontroller.safetycenter.ui.model.ActionId +import com.android.permissioncontroller.safetycenter.ui.model.IssueId +import com.android.permissioncontroller.safetycenter.ui.model.IssueUiData import com.android.permissioncontroller.safetycenter.ui.model.SafetyCenterUiData import com.android.safetycenter.internaldata.SafetyCenterBundles.ISSUES_TO_GROUPS_BUNDLE_KEY +import com.android.safetycenter.internaldata.SafetyCenterIds +import com.android.safetycenter.internaldata.SafetyCenterIssueId +import com.android.safetycenter.internaldata.SafetyCenterIssueKey import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @@ -40,42 +47,42 @@ class SafetyCenterUiDataTest { @Test fun getMatchingGroup_validMatchingGroup_returnsExpectedEntryGroup() { - val matchingGroup = createSafetyCenterEntryGroup(MATCHING_GROUP_ID) - val nonMatchingGroup = createSafetyCenterEntryGroup(NON_MATCHING_GROUP_ID) + val matchingGroup = entryGroup(MATCHING_GROUP_ID) + val nonMatchingGroup = entryGroup(NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData(entryGroups = listOf(matchingGroup, nonMatchingGroup)) - val result = SafetyCenterUiData(safetyCenterData).getMatchingGroup(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingGroup(MATCHING_GROUP_ID) assertThat(result).isEqualTo(matchingGroup) } @Test fun getMatchingGroup_noMatchingGroup_returnsNull() { - val nonMatchingGroup = createSafetyCenterEntryGroup(NON_MATCHING_GROUP_ID) + val nonMatchingGroup = entryGroup(NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData(entryGroups = listOf(nonMatchingGroup)) - val result = SafetyCenterUiData(safetyCenterData).getMatchingGroup(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingGroup(MATCHING_GROUP_ID) assertThat(result).isNull() } @Test fun getMatchingIssues_defaultMatchingIssue_noExtras_returnsListOfIssues() { - val defaultMatchingIssue = createSafetyCenterIssue("id1", MATCHING_GROUP_ID) - val nonMatchingIssue = createSafetyCenterIssue("id2", NON_MATCHING_GROUP_ID) + val defaultMatchingIssue = issue("id1", MATCHING_GROUP_ID) + val nonMatchingIssue = issue("id2", NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData(issues = listOf(defaultMatchingIssue, nonMatchingIssue)) - val result = SafetyCenterUiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) assertThat(result).containsExactly(defaultMatchingIssue) } @Test fun getMatchingIssues_defaultMatchingIssue_unrelatedExtras_returnsListOfIssues() { - val defaultMatchingIssue = createSafetyCenterIssue("id1", MATCHING_GROUP_ID) - val nonMatchingIssue = createSafetyCenterIssue("id2", NON_MATCHING_GROUP_ID) + val defaultMatchingIssue = issue("id1", MATCHING_GROUP_ID) + val nonMatchingIssue = issue("id2", NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( issues = listOf(defaultMatchingIssue, nonMatchingIssue), @@ -84,21 +91,21 @@ class SafetyCenterUiDataTest { Bundle().apply { putStringArrayList( nonMatchingIssue.id, - arrayListOf(NON_MATCHING_GROUP_ID) + arrayListOf(NON_MATCHING_GROUP_ID), ) } - ) + ), ) - val result = SafetyCenterUiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) assertThat(result).containsExactly(defaultMatchingIssue) } @Test fun getMatchingIssues_mappingMatchingIssue_returnsListOfIssues() { - val mappingMatchingIssue = createSafetyCenterIssue("id1", NON_MATCHING_GROUP_ID) - val nonMatchingIssue = createSafetyCenterIssue("id2", NON_MATCHING_GROUP_ID) + val mappingMatchingIssue = issue("id1", NON_MATCHING_GROUP_ID) + val nonMatchingIssue = issue("id2", NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( issues = listOf(mappingMatchingIssue, nonMatchingIssue), @@ -107,51 +114,50 @@ class SafetyCenterUiDataTest { Bundle().apply { putStringArrayList( mappingMatchingIssue.id, - arrayListOf(MATCHING_GROUP_ID) + arrayListOf(MATCHING_GROUP_ID), ) } - ) + ), ) - val result = SafetyCenterUiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) assertThat(result).containsExactly(mappingMatchingIssue) } @Test fun getMatchingIssues_noDefaultMatchingIssue_returnsEmptyList() { - val nonMatchingIssue = createSafetyCenterIssue("id1", NON_MATCHING_GROUP_ID) - val dismissedIssue = createSafetyCenterIssue("id2", MATCHING_GROUP_ID) + val nonMatchingIssue = issue("id1", NON_MATCHING_GROUP_ID) + val dismissedIssue = issue("id2", MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( issues = listOf(nonMatchingIssue), - dismissedIssues = listOf(dismissedIssue) + dismissedIssues = listOf(dismissedIssue), ) - val result = SafetyCenterUiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingIssues(MATCHING_GROUP_ID) assertThat(result).isEmpty() } @Test fun getMatchingDismissedIssues_defaultMatchingDismissedIssue_returnsListOfDismissedIssues() { - val defaultMatchingDismissedIssue = createSafetyCenterIssue("id1", MATCHING_GROUP_ID) - val nonMatchingDismissedIssue = createSafetyCenterIssue("id2", NON_MATCHING_GROUP_ID) + val defaultMatchingDismissedIssue = issue("id1", MATCHING_GROUP_ID) + val nonMatchingDismissedIssue = issue("id2", NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( dismissedIssues = listOf(defaultMatchingDismissedIssue, nonMatchingDismissedIssue) ) - val result = - SafetyCenterUiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) assertThat(result).containsExactly(defaultMatchingDismissedIssue) } @Test fun getMatchingDismissedIssues_defaultMatchingDismissedIssue2_returnsListOfDismissedIssues() { - val defaultMatchingDismissedIssue = createSafetyCenterIssue("id1", MATCHING_GROUP_ID) - val nonMatchingDismissedIssue = createSafetyCenterIssue("id2", NON_MATCHING_GROUP_ID) + val defaultMatchingDismissedIssue = issue("id1", MATCHING_GROUP_ID) + val nonMatchingDismissedIssue = issue("id2", NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( dismissedIssues = listOf(defaultMatchingDismissedIssue, nonMatchingDismissedIssue), @@ -160,22 +166,21 @@ class SafetyCenterUiDataTest { Bundle().apply { putStringArrayList( nonMatchingDismissedIssue.id, - arrayListOf(NON_MATCHING_GROUP_ID) + arrayListOf(NON_MATCHING_GROUP_ID), ) } - ) + ), ) - val result = - SafetyCenterUiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) assertThat(result).containsExactly(defaultMatchingDismissedIssue) } @Test fun getMatchingDismissedIssues_mappingMatchingDismissedIssue_returnsListOfDismissedIssues() { - val mappingMatchingDismissedIssue = createSafetyCenterIssue("id1", NON_MATCHING_GROUP_ID) - val nonMatchingDismissedIssue = createSafetyCenterIssue("id2", NON_MATCHING_GROUP_ID) + val mappingMatchingDismissedIssue = issue("id1", NON_MATCHING_GROUP_ID) + val nonMatchingDismissedIssue = issue("id2", NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( dismissedIssues = listOf(mappingMatchingDismissedIssue, nonMatchingDismissedIssue), @@ -184,30 +189,28 @@ class SafetyCenterUiDataTest { Bundle().apply { putStringArrayList( mappingMatchingDismissedIssue.id, - arrayListOf(MATCHING_GROUP_ID) + arrayListOf(MATCHING_GROUP_ID), ) } - ) + ), ) - val result = - SafetyCenterUiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) assertThat(result).containsExactly(mappingMatchingDismissedIssue) } @Test fun getMatchingDismissedIssues_noDefaultMatchingDismissedIssue_returnsEmptyList() { - val nonMatchingDismissedIssue = createSafetyCenterIssue("id1", NON_MATCHING_GROUP_ID) - val nonDismissedIssue = createSafetyCenterIssue("id2", MATCHING_GROUP_ID) + val nonMatchingDismissedIssue = issue("id1", NON_MATCHING_GROUP_ID) + val nonDismissedIssue = issue("id2", MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( issues = listOf(nonDismissedIssue), - dismissedIssues = listOf(nonMatchingDismissedIssue) + dismissedIssues = listOf(nonMatchingDismissedIssue), ) - val result = - SafetyCenterUiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) assertThat(result).isEmpty() } @@ -215,24 +218,12 @@ class SafetyCenterUiDataTest { @Test fun getMatchingDismissedIssues_doesntReturnGreenIssues() { val greenDismissedIssue = - createSafetyCenterIssue( - "id1", - MATCHING_GROUP_ID, - severityLevel = ISSUE_SEVERITY_LEVEL_OK - ) + issue("id1", MATCHING_GROUP_ID, severityLevel = ISSUE_SEVERITY_LEVEL_OK) val yellowDismissedIssue = - createSafetyCenterIssue( - "id2", - MATCHING_GROUP_ID, - severityLevel = ISSUE_SEVERITY_LEVEL_RECOMMENDATION - ) + issue("id2", MATCHING_GROUP_ID, severityLevel = ISSUE_SEVERITY_LEVEL_RECOMMENDATION) val redDismissedIssue = - createSafetyCenterIssue( - "id3", - MATCHING_GROUP_ID, - severityLevel = ISSUE_SEVERITY_LEVEL_CRITICAL_WARNING - ) - val nonMatchingDismissedIssue = createSafetyCenterIssue("id4", NON_MATCHING_GROUP_ID) + issue("id3", MATCHING_GROUP_ID, severityLevel = ISSUE_SEVERITY_LEVEL_CRITICAL_WARNING) + val nonMatchingDismissedIssue = issue("id4", NON_MATCHING_GROUP_ID) val safetyCenterData = createSafetyCenterData( dismissedIssues = @@ -240,25 +231,82 @@ class SafetyCenterUiDataTest { redDismissedIssue, yellowDismissedIssue, greenDismissedIssue, - nonMatchingDismissedIssue - ), + nonMatchingDismissedIssue, + ) ) - val result = - SafetyCenterUiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) + val result = uiData(safetyCenterData).getMatchingDismissedIssues(MATCHING_GROUP_ID) assertThat(result).containsExactly(redDismissedIssue, yellowDismissedIssue).inOrder() } + @Test + fun issueUiDatas_returnsIssueUiData() { + val issue1 = issue("id1", "group1") + val issue2 = issue("id2", "group2") + val safetyCenterData = createSafetyCenterData(listOf(issue1, issue2)) + + val result = uiData(safetyCenterData).issueUiDatas + + assertThat(result) + .containsExactly( + IssueUiData(issue1, isDismissed = false), + IssueUiData(issue2, isDismissed = false), + ) + .inOrder() + } + + @Test + fun issueUiDatas_withResolvedIssues_returnsExpectedIssueUiData() { + val resolvedActionId = "actionId" + val resolvedIssue = issue("resolvedId", "group1") + val unresolvedIssue = issue("unresolvedId", "group2") + val safetyCenterData = createSafetyCenterData(listOf(resolvedIssue, unresolvedIssue)) + + val result = + uiData(safetyCenterData, resolvedIssues = mapOf(resolvedIssue.id to resolvedActionId)) + .issueUiDatas + + assertThat(result[0].resolvedIssueActionId).isEqualTo(resolvedActionId) + assertThat(result[1].resolvedIssueActionId).isNull() + } + + @Test + fun issueUiDatas_withSameTaskSourceId_returnsExpectedIssueUiData() { + val taskId = 42 + val sameTaskSourceId = "sameTaskSourceId" + val sameTaskIssue = + issueWithEncodedId( + encodeIssueId("sameTaskIssue", sourceId = sameTaskSourceId), + "group1", + ) + val differentTaskIssue = issue("differentTaskIssue", "group2") + val safetyCenterData = createSafetyCenterData(listOf(sameTaskIssue, differentTaskIssue)) + + val result = + uiData(safetyCenterData, taskId, sameTaskSourceIds = listOf(sameTaskSourceId)) + .issueUiDatas + + assertThat(result[0].launchTaskId).isEqualTo(taskId) + assertThat(result[1].launchTaskId).isNull() + } + private companion object { const val MATCHING_GROUP_ID = "matching_group_id" const val NON_MATCHING_GROUP_ID = "non_matching_group_id" + private fun uiData( + safetyCenterData: SafetyCenterData, + taskId: Int = 0, + sameTaskSourceIds: List<String> = emptyList(), + resolvedIssues: Map<IssueId, ActionId> = emptyMap(), + ) = SafetyCenterUiData(safetyCenterData, taskId, sameTaskSourceIds, resolvedIssues) + fun createSafetyCenterData( issues: List<SafetyCenterIssue> = listOf(), entryGroups: List<SafetyCenterEntryGroup> = listOf(), dismissedIssues: List<SafetyCenterIssue> = listOf(), - extras: Bundle = Bundle() + extras: Bundle = Bundle(), ): SafetyCenterData { val safetyCenterStatus = SafetyCenterStatus.Builder("status title", "status summary").build() @@ -276,20 +324,44 @@ class SafetyCenterUiDataTest { return builder.build() } - fun createSafetyCenterEntryGroup(groupId: String) = + fun createSafetyCenterExtras(issuesToGroupsMapping: Bundle) = + Bundle().apply { putBundle(ISSUES_TO_GROUPS_BUNDLE_KEY, issuesToGroupsMapping) } + + fun entryGroup(groupId: String) = SafetyCenterEntryGroup.Builder(groupId, "group title").build() - fun createSafetyCenterIssue( + fun issue( issueId: String, groupId: String, - severityLevel: Int = ISSUE_SEVERITY_LEVEL_RECOMMENDATION + severityLevel: Int = ISSUE_SEVERITY_LEVEL_RECOMMENDATION, + ): SafetyCenterIssue = issueWithEncodedId(encodeIssueId(issueId), groupId, severityLevel) + + private fun issueWithEncodedId( + encodedIssueId: String, + groupId: String, + severityLevel: Int = ISSUE_SEVERITY_LEVEL_RECOMMENDATION, ) = - SafetyCenterIssue.Builder(issueId, "issue title", "issue summary") + SafetyCenterIssue.Builder(encodedIssueId, "issue title", "issue summary") .setSeverityLevel(severityLevel) .setGroupId(groupId) .build() - fun createSafetyCenterExtras(issuesToGroupsMapping: Bundle) = - Bundle().apply { putBundle(ISSUES_TO_GROUPS_BUNDLE_KEY, issuesToGroupsMapping) } + fun encodeIssueId( + sourceIssueId: String, + sourceId: String = "defaultSource", + issueTypeId: String = "defaultIssueTypeId", + ): String = + SafetyCenterIds.encodeToString( + SafetyCenterIssueId.newBuilder() + .setSafetyCenterIssueKey( + SafetyCenterIssueKey.newBuilder() + .setSafetySourceId(sourceId) + .setSafetySourceIssueId(sourceIssueId) + .setUserId(UserHandle.myUserId()) + .build() + ) + .setIssueTypeId(issueTypeId) + .build() + ) } } diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt index f0dab21ec..23074a06f 100644 --- a/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt +++ b/PermissionController/wear-permission-components/src/wear.permission.components/material2/Chip.kt @@ -33,7 +33,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.Hyphens import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow @@ -194,11 +193,7 @@ fun Chip( textAlign = if (hasSecondaryLabel || hasIcon) TextAlign.Start else TextAlign.Center, overflow = TextOverflow.Ellipsis, maxLines = labelMaxLines ?: if (hasSecondaryLabel) 1 else 2, - style = - MaterialTheme.typography.button.copy( - fontWeight = FontWeight.W600, - hyphens = Hyphens.Auto, - ), + style = MaterialTheme.typography.button.copy(hyphens = Hyphens.Auto), ) } diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material2/ListHeader.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material2/ListHeader.kt index 7dc26179d..6ed81353a 100644 --- a/PermissionController/wear-permission-components/src/wear.permission.components/material2/ListHeader.kt +++ b/PermissionController/wear-permission-components/src/wear.permission.components/material2/ListHeader.kt @@ -34,7 +34,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.semantics.heading import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.Hyphens import androidx.compose.ui.unit.dp import androidx.wear.compose.material.LocalContentColor @@ -72,11 +71,7 @@ fun ListHeader( ) { CompositionLocalProvider( LocalContentColor provides contentColor, - LocalTextStyle provides - MaterialTheme.typography.title3.copy( - fontWeight = FontWeight.W600, - hyphens = Hyphens.Auto, - ), + LocalTextStyle provides MaterialTheme.typography.title3.copy(hyphens = Hyphens.Auto), ) { content() } diff --git a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt index 1a7524e7c..5f1c8dd2c 100644 --- a/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt +++ b/PermissionController/wear-permission-components/src/wear.permission.components/material3/WearPermissionButton.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.requiredSizeIn import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.Hyphens import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -112,11 +111,7 @@ internal fun WearPermissionButtonInternal( text = label, modifier = Modifier.fillMaxWidth(), maxLines = labelMaxLines ?: LocalTextConfiguration.current.maxLines, - style = - LocalTextStyle.current.copy( - fontWeight = FontWeight.W600, - hyphens = Hyphens.Auto, - ), + style = LocalTextStyle.current.copy(hyphens = Hyphens.Auto), ) } } diff --git a/SafetyCenter/OWNERS b/SafetyCenter/OWNERS index d9039e915..229331d3c 100644 --- a/SafetyCenter/OWNERS +++ b/SafetyCenter/OWNERS @@ -4,7 +4,6 @@ simonjw@google.com davidcoffin@google.com elliotsisteron@google.com fiscella@google.com -shrigupt@google.com jtomljanovic@google.com deweytyl@google.com maxspencer@google.com diff --git a/SafetyCenter/Resources/res/values-mk-v35/strings.xml b/SafetyCenter/Resources/res/values-mk-v35/strings.xml index c4fc4bd17..1201ae74f 100644 --- a/SafetyCenter/Resources/res/values-mk-v35/strings.xml +++ b/SafetyCenter/Resources/res/values-mk-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-mk/strings.xml b/SafetyCenter/Resources/res/values-mk/strings.xml index 2b2414d0d..379a5234b 100644 --- a/SafetyCenter/Resources/res/values-mk/strings.xml +++ b/SafetyCenter/Resources/res/values-mk/strings.xml @@ -33,9 +33,9 @@ <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="privacy_controls_title" msgid="5322875777945432395">"Контроли за приватноста"</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> + <string name="privacy_controls_search_terms" msgid="3774472175934304165">"Приватност, Контроли за приватност"</string> <string name="advanced_title" msgid="8745436380690561172">"Повеќе поставки"</string> <string name="advanced_security_title" msgid="1126833338772188155">"Повеќе поставки за безбедност"</string> <string name="advanced_security_summary" msgid="6172253327022425123">"Шифрирање, акредитиви и друго"</string> diff --git a/service/java/com/android/permission/util/UserUtils.java b/service/java/com/android/permission/util/UserUtils.java index 82e9cbbae..ae8e794b6 100644 --- a/service/java/com/android/permission/util/UserUtils.java +++ b/service/java/com/android/permission/util/UserUtils.java @@ -70,8 +70,7 @@ public final class UserUtils { return; } - Context userContext = UserUtils.getUserContext(userId, context); - List<UserHandle> profiles = getUserProfiles(userContext, true); + List<UserHandle> profiles = getUserProfiles(userId, context, true); final int profilesSize = profiles.size(); for (int i = 0; i < profilesSize; i++) { int profileId = profiles.get(i).getIdentifier(); @@ -112,26 +111,29 @@ public final class UserUtils { } } - /** Returns all the enabled user profiles on the device. */ + /** Returns all the enabled user profiles on the device for a specified user. */ @NonNull - public static List<UserHandle> getUserProfiles(@NonNull Context context) { - return getUserProfiles(context, false); + public static List<UserHandle> getUserProfiles(@UserIdInt int userId, + @NonNull Context context) { + return getUserProfiles(userId, context, false); } /** - * Returns all the enabled user profiles on the device + * Returns all the enabled user profiles on the device for a specified user * + * @param userId the user id to check * @param context the {@link Context} * @param excludePrivate {@code true} to exclude private profiles from returned list of users */ @NonNull - public static List<UserHandle> getUserProfiles(@NonNull Context context, + public static List<UserHandle> getUserProfiles(@UserIdInt int userId, @NonNull Context context, boolean excludePrivate) { - UserManager userManager = context.getSystemService(UserManager.class); // This call requires the QUERY_USERS permission. final long identity = Binder.clearCallingIdentity(); try { - List<UserHandle> profiles = userManager.getUserProfiles(); + Context userContext = getUserContext(userId, context); + UserManager userUserManager = userContext.getSystemService(UserManager.class); + List<UserHandle> profiles = userUserManager.getUserProfiles(); if (!excludePrivate) { return profiles; } @@ -139,7 +141,7 @@ public final class UserUtils { final int profilesSize = profiles.size(); for (int i = 0; i < profilesSize; i++) { UserHandle user = profiles.get(i); - if (!isPrivateProfile(user.getIdentifier(), context)) { + if (!isPrivateProfile(user.getIdentifier(), userContext)) { filteredProfiles.add(user); } } @@ -164,11 +166,11 @@ public final class UserUtils { @Nullable private static UserHandle getProfileParent(@UserIdInt int userId, @NonNull Context context) { Context userContext = getUserContext(userId, context); - UserManager userManager = userContext.getSystemService(UserManager.class); + UserManager userUserManager = userContext.getSystemService(UserManager.class); // This call requires the INTERACT_ACROSS_USERS permission. final long identity = Binder.clearCallingIdentity(); try { - return userManager.getProfileParent(UserHandle.of(userId)); + return userUserManager.getProfileParent(UserHandle.of(userId)); } finally { Binder.restoreCallingIdentity(identity); } @@ -201,8 +203,8 @@ public final class UserUtils { final long identity = Binder.clearCallingIdentity(); try { Context userContext = getUserContext(userId, context); - UserManager userManager = userContext.getSystemService(UserManager.class); - return userManager != null && userManager.isPrivateProfile(); + UserManager userUserManager = userContext.getSystemService(UserManager.class); + return userUserManager != null && userUserManager.isPrivateProfile(); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java index 5bc79efbb..e5d20ef9d 100644 --- a/service/java/com/android/role/RoleService.java +++ b/service/java/com/android/role/RoleService.java @@ -564,8 +564,7 @@ public class RoleService extends SystemService implements RoleUserState.Callback + " for role"); return; } - Context userContext = UserUtils.getUserContext(userId, getContext()); - List<UserHandle> profiles = UserUtils.getUserProfiles(userContext, true); + List<UserHandle> profiles = UserUtils.getUserProfiles(userId, getContext(), true); if (!profiles.contains(UserHandle.of(activeUserId))) { Log.e(LOG_TAG, "User " + activeUserId + " is not in the same profile-group as " + userId); diff --git a/service/java/com/android/safetycenter/UserProfileGroup.java b/service/java/com/android/safetycenter/UserProfileGroup.java index 1f5258437..44cb8d3d6 100644 --- a/service/java/com/android/safetycenter/UserProfileGroup.java +++ b/service/java/com/android/safetycenter/UserProfileGroup.java @@ -129,9 +129,8 @@ public final class UserProfileGroup { * is disabled. */ public static UserProfileGroup fromUser(Context context, @UserIdInt int userId) { - Context userContext = UserUtils.getUserContext(userId, context); - List<UserHandle> userProfiles = UserUtils.getUserProfiles(userContext); - int profileParentUserId = UserUtils.getProfileParentIdOrSelf(userId, userContext); + List<UserHandle> userProfiles = UserUtils.getUserProfiles(userId, context); + int profileParentUserId = UserUtils.getProfileParentIdOrSelf(userId, context); int[] managedProfilesUserIds = new int[userProfiles.size()]; int[] managedRunningProfilesUserIds = new int[userProfiles.size()]; diff --git a/tests/cts/permissionpolicy/res/raw/android_manifest.xml b/tests/cts/permissionpolicy/res/raw/android_manifest.xml index cd80fe78e..ceefe3dfd 100644 --- a/tests/cts/permissionpolicy/res/raw/android_manifest.xml +++ b/tests/cts/permissionpolicy/res/raw/android_manifest.xml @@ -7759,7 +7759,17 @@ @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @hide --> <permission android:name="android.permission.READ_BLOCKED_NUMBERS" - android:protectionLevel="signature" /> + android:protectionLevel="signature" + android:featureFlag="!android.permission.flags.grant_read_blocked_numbers_to_system_ui_intelligence" /> + + <!-- Allows the holder to read blocked numbers. See + {@link android.provider.BlockedNumberContract}. + @SystemApi + @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") + @hide --> + <permission android:name="android.permission.READ_BLOCKED_NUMBERS" + android:protectionLevel="signature|role" + android:featureFlag="android.permission.flags.grant_read_blocked_numbers_to_system_ui_intelligence" /> <!-- Allows the holder to write blocked numbers. See {@link android.provider.BlockedNumberContract}. diff --git a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt index ccc5a0a5e..f52e32344 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/BaseUsePermissionTest.kt @@ -38,6 +38,7 @@ import android.provider.DeviceConfig import android.provider.Settings import android.text.Spanned import android.text.style.ClickableSpan +import android.util.Log import android.view.View import android.view.accessibility.AccessibilityNodeInfo import androidx.test.uiautomator.By @@ -51,6 +52,7 @@ import com.android.compatibility.common.util.SystemUtil import com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity import com.android.compatibility.common.util.SystemUtil.eventually import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity +import com.android.compatibility.common.util.UiDumpUtils import com.android.modules.utils.build.SdkLevel import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit @@ -64,6 +66,7 @@ import org.junit.Before abstract class BaseUsePermissionTest : BasePermissionTest() { companion object { + const val LOG_TAG = "BaseUsePermissionTest" const val APP_APK_NAME_31 = "CtsUsePermissionApp31.apk" const val APP_APK_NAME_31_WITH_ASL = "CtsUsePermissionApp31WithAsl.apk" const val APP_APK_NAME_LATEST = "CtsUsePermissionAppLatest.apk" @@ -791,6 +794,9 @@ abstract class BaseUsePermissionTest : BasePermissionTest() { ) if (timeoutOccurred) { + val uiDump = StringBuilder() + UiDumpUtils.dumpNodes(uiDump) + Log.w(LOG_TAG, "Timed out waiting for window transition, UI dump: $uiDump") throw RuntimeException("Timed out waiting for window transition.") } } diff --git a/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt index be4b82932..4781fb895 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/LocationAccuracyTest.kt @@ -72,6 +72,8 @@ class LocationAccuracyTest : BaseUsePermissionTest() { } @Test + @Ignore("b/396478581") + // Ignore this test until the cause of flakiness is identified. fun testPrecisePermissionIsGranted() { installPackage(APP_APK_PATH_31) diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt index 751c56b3c..9a12765c0 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PermissionRationalePermissionGrantDialogTest.kt @@ -41,8 +41,7 @@ import org.junit.Test @FlakyTest class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { - @get:Rule - val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() + @get:Rule val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() @get:Rule val deviceConfigPermissionRationaleEnabled = @@ -50,7 +49,7 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { context, DeviceConfig.NAMESPACE_PRIVACY, PERMISSION_RATIONALE_ENABLED, - true.toString() + true.toString(), ) @Before @@ -248,8 +247,10 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { } } - @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = - "VanillaIceCream") + @SdkSuppress( + minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, + codeName = "VanillaIceCream", + ) @RequiresFlagsEnabled(android.content.pm.Flags.FLAG_ASL_IN_APK_APP_METADATA_SOURCE) @Test fun requestCoarseLocationPerm_hasAslInApk_packageSourceUnspecified() { @@ -262,8 +263,10 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { } } - @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = - "VanillaIceCream") + @SdkSuppress( + minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, + codeName = "VanillaIceCream", + ) @RequiresFlagsEnabled(android.content.pm.Flags.FLAG_ASL_IN_APK_APP_METADATA_SOURCE) @Test fun requestCoarseLocationPerm_hasAslInApk_packageSourceStore() { @@ -276,8 +279,10 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { } } - @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = - "VanillaIceCream") + @SdkSuppress( + minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, + codeName = "VanillaIceCream", + ) @RequiresFlagsEnabled(android.content.pm.Flags.FLAG_ASL_IN_APK_APP_METADATA_SOURCE) @Test fun requestCoarseLocationPerm_hasAslInApk_packageSourceLocalFile() { @@ -290,8 +295,10 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { } } - @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = - "VanillaIceCream") + @SdkSuppress( + minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, + codeName = "VanillaIceCream", + ) @RequiresFlagsEnabled(android.content.pm.Flags.FLAG_ASL_IN_APK_APP_METADATA_SOURCE) @Test fun requestCoarseLocationPerm_hasAslInApk_packageSourceDownloadedFile() { @@ -304,8 +311,10 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { } } - @SdkSuppress(minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, codeName = - "VanillaIceCream") + @SdkSuppress( + minSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM, + codeName = "VanillaIceCream", + ) @RequiresFlagsEnabled(android.content.pm.Flags.FLAG_ASL_IN_APK_APP_METADATA_SOURCE) @Test fun requestCoarseLocationPerm_hasAslInApk_packageSourceOther() { @@ -338,7 +347,6 @@ class PermissionRationalePermissionGrantDialogTest : BaseUsePermissionTest() { requestAppPermissionsForNoResult(ACCESS_FINE_LOCATION) { clickPermissionRationaleViewInGrantDialog() assertPermissionRationaleDialogIsVisible(true) - assertPermissionRationaleContainerOnGrantDialogIsVisible(false) } } diff --git a/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt b/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt index 98aa5fbf1..dc2ba42c6 100644 --- a/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt +++ b/tests/cts/rolemultiuser/src/android/app/rolemultiuser/cts/RoleManagerMultiUserTest.kt @@ -27,10 +27,12 @@ import android.os.Process import android.os.UserHandle import android.os.UserManager.DISALLOW_CONFIG_DEFAULT_APPS import android.provider.Settings +import android.util.Log import android.util.Pair import androidx.test.filters.SdkSuppress import androidx.test.rule.ActivityTestRule import androidx.test.uiautomator.By +import com.android.bedstead.enterprise.annotations.EnsureDoesNotHaveUserRestriction import com.android.bedstead.enterprise.annotations.EnsureHasNoWorkProfile import com.android.bedstead.enterprise.annotations.EnsureHasUserRestriction import com.android.bedstead.enterprise.annotations.EnsureHasWorkProfile @@ -53,6 +55,7 @@ import com.android.bedstead.nene.TestApis.context import com.android.bedstead.nene.TestApis.permissions import com.android.bedstead.nene.TestApis.users import com.android.bedstead.nene.types.OptionalBoolean +import com.android.bedstead.nene.userrestrictions.CommonUserRestrictions.DISALLOW_ADD_MANAGED_PROFILE import com.android.bedstead.nene.users.UserReference import com.android.bedstead.nene.users.UserType import com.android.bedstead.permissions.CommonPermissions.INTERACT_ACROSS_USERS_FULL @@ -69,7 +72,6 @@ import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObject import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObjectOrNull import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage -import java.util.Objects import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit import java.util.function.Consumer @@ -94,16 +96,24 @@ class RoleManagerMultiUserTest { ActivityTestRule(WaitForResultActivity::class.java) @Before - @Throws(java.lang.Exception::class) fun setUp() { assumeTrue(RoleManagerUtil.isCddCompliantScreenSize()) installAppForAllUsers() + + // If "none" selected in test, ensure we re-enable fallback for other test runs + permissions().withPermission(MANAGE_ROLE_HOLDERS, INTERACT_ACROSS_USERS_FULL).use { + setRoleFallbackEnabledForAllUsers() + } } @After - @Throws(java.lang.Exception::class) fun tearDown() { uninstallAppForAllUsers() + + // If "none" selected in test, ensure we re-enable fallback for other test runs + permissions().withPermission(MANAGE_ROLE_HOLDERS, INTERACT_ACROSS_USERS_FULL).use { + setRoleFallbackEnabledForAllUsers() + } } @RequireFlagsEnabled(com.android.permission.flags.Flags.FLAG_CROSS_USER_ROLE_ENABLED) @@ -315,7 +325,7 @@ class RoleManagerMultiUserTest { // initialUser needs to be not the targetUser val targetActiveUser = users().current().userHandle() val initialUser = - if (Objects.equals(targetActiveUser, deviceState.initialUser().userHandle())) { + if (targetActiveUser == deviceState.initialUser().userHandle()) { deviceState.workProfile().userHandle() } else { deviceState.initialUser().userHandle() @@ -378,7 +388,7 @@ class RoleManagerMultiUserTest { val initialUser = deviceState.workProfile().userHandle() // setActiveUserForRole and getActiveUserForRole is used to ensure initial active users // state and requires INTERACT_ACROSS_USERS_FULL - permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { roleManager.setActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, initialUser, 0) assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(initialUser) @@ -406,7 +416,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole is used to ensure addRoleHolderAsUser didn't set active user, and // requires INTERACT_ACROSS_USERS_FULL - permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(initialUser) } @@ -483,7 +493,7 @@ class RoleManagerMultiUserTest { val initialUser = deviceState.workProfile().userHandle() // setActiveUserForRole and getActiveUserForRole is used to ensure initial active users // state and requires INTERACT_ACROSS_USERS_FULL - permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { roleManager.setActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, initialUser, 0) assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(initialUser) @@ -503,7 +513,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole is used to ensure setDefaultApplication didn't set active user, // and requires INTERACT_ACROSS_USERS_FULL - permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(initialUser) } @@ -570,6 +580,7 @@ class RoleManagerMultiUserTest { @EnsureCanAddUser @EnsureHasNoWorkProfile @RequireRunOnPrimaryUser + @EnsureDoesNotHaveUserRestriction(DISALLOW_ADD_MANAGED_PROFILE) @Test @Throws(Exception::class) fun ensureActiveUserSetToParentOnUserRemoved() { @@ -1279,7 +1290,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -1306,7 +1317,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role // holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(targetActiveUser) assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser) @@ -1315,7 +1326,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -1332,7 +1343,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -1359,7 +1370,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role // holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(targetActiveUser) assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser) @@ -1368,7 +1379,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -1385,7 +1396,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -1410,7 +1421,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role // holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(deviceState.initialUser().userHandle()) assertNoRoleHoldersUsingGetRoleHoldersAsUser() @@ -1419,7 +1430,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -1436,7 +1447,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -1463,7 +1474,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role // holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(targetActiveUser) assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser) @@ -1472,7 +1483,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -1489,7 +1500,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -1516,7 +1527,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role // holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(targetActiveUser) assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser) @@ -1525,7 +1536,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -1542,7 +1553,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -1567,7 +1578,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role // holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(deviceState.initialUser().userHandle()) assertNoRoleHoldersUsingGetRoleHoldersAsUser() @@ -1576,7 +1587,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -1645,7 +1656,12 @@ class RoleManagerMultiUserTest { getUiDevice().waitForIdle() // CollapsingToolbar title can't be found by text, so using description instead. - assertNull(waitFindObjectOrNull(By.desc(PROFILE_GROUP_EXCLUSIVITY_ROLE_LABEL))) + assertNull( + waitFindObjectOrNull( + By.desc(PROFILE_GROUP_EXCLUSIVITY_ROLE_LABEL), + IDLE_TIMEOUT_MILLIS, + ) + ) pressBack() pressBack() @@ -1681,7 +1697,12 @@ class RoleManagerMultiUserTest { getUiDevice().waitForIdle() // CollapsingToolbar title can't be found by text, so using description instead. - assertNull(waitFindObjectOrNull(By.desc(PROFILE_GROUP_EXCLUSIVITY_ROLE_LABEL))) + assertNull( + waitFindObjectOrNull( + By.desc(PROFILE_GROUP_EXCLUSIVITY_ROLE_LABEL), + IDLE_TIMEOUT_MILLIS, + ) + ) pressBack() pressBack() @@ -1816,7 +1837,8 @@ class RoleManagerMultiUserTest { if (isWatch) { assertNull( waitFindObjectOrNull( - By.clickable(true).checked(true).hasDescendant(By.text(targetAppLabel)) + By.clickable(true).checked(true).hasDescendant(By.text(targetAppLabel)), + IDLE_TIMEOUT_MILLIS, ) ) } else { @@ -1824,7 +1846,8 @@ class RoleManagerMultiUserTest { waitFindObjectOrNull( By.clickable(true) .hasDescendant(By.checkable(true).checked(true)) - .hasDescendant(By.text(targetAppLabel)) + .hasDescendant(By.text(targetAppLabel)), + IDLE_TIMEOUT_MILLIS, ) ) } @@ -1895,7 +1918,8 @@ class RoleManagerMultiUserTest { if (isWatch) { assertNull( waitFindObjectOrNull( - By.clickable(true).checked(true).hasDescendant(By.text(targetAppLabel)) + By.clickable(true).checked(true).hasDescendant(By.text(targetAppLabel)), + IDLE_TIMEOUT_MILLIS, ) ) } else { @@ -1903,7 +1927,8 @@ class RoleManagerMultiUserTest { waitFindObjectOrNull( By.clickable(true) .hasDescendant(By.checkable(true).checked(true)) - .hasDescendant(By.text(targetAppLabel)) + .hasDescendant(By.text(targetAppLabel)), + IDLE_TIMEOUT_MILLIS, ) ) } @@ -1934,7 +1959,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -1961,7 +1986,7 @@ class RoleManagerMultiUserTest { // getActiveUserForRole and getRoleHoldersAsUser require INTERACT_ACROSS_USERS_FULL and // MANAGE_ROLE_HOLDERS permissions to validate cross user role active user and role // holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { assertThat(roleManager.getActiveUserForRole(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME)) .isEqualTo(targetActiveUser) assertExpectedProfileHasRoleUsingGetRoleHoldersAsUser(targetActiveUser) @@ -1970,7 +1995,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -1991,7 +2016,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -2016,7 +2041,7 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } @@ -2037,7 +2062,7 @@ class RoleManagerMultiUserTest { // setDefaultHoldersForTestForAllUsers and setRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { // Set test default role holder. Ensures fallbacks to a default holder setDefaultHoldersForTestForAllUsers() setRoleVisibleForTestForAllUsers() @@ -2062,17 +2087,15 @@ class RoleManagerMultiUserTest { // clearDefaultHoldersForTestForAllUsers and clearRoleVisibleForTestForAllUsers require // INTERACT_ACROSS_USERS_FULL and MANAGE_ROLE_HOLDERS permissions to validate cross user // role active user and role holder states - permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { _ -> + permissions().withPermission(INTERACT_ACROSS_USERS_FULL, MANAGE_ROLE_HOLDERS).use { clearDefaultHoldersForTestForAllUsers() clearRoleVisibleForTestForAllUsers() } } } - @Throws(java.lang.Exception::class) private fun installAppForAllUsers() { SystemUtil.runShellCommandOrThrow("pm install -r --user all $APP_APK_PATH") - SystemUtil.waitForBroadcasts() } private fun uninstallAppForAllUsers() { @@ -2099,8 +2122,7 @@ class RoleManagerMultiUserTest { } val result: Pair<Int, Intent?> = clickButtonAndWaitForResult(allow) val expectedResult = - if (allow && Objects.equals(targetActiveUser, users().instrumented().userHandle())) - Activity.RESULT_OK + if (allow && targetActiveUser == users().instrumented().userHandle()) Activity.RESULT_OK else Activity.RESULT_CANCELED assertThat(result.first).isEqualTo(expectedResult) @@ -2118,7 +2140,8 @@ class RoleManagerMultiUserTest { } private fun roleRequestNotShown() { - val requestRoleItem = waitFindObjectOrNull(By.textStartsWith(APP_LABEL)) + val requestRoleItem = + waitFindObjectOrNull(By.textStartsWith(APP_LABEL), IDLE_TIMEOUT_MILLIS) assertNull(requestRoleItem) val result: Pair<Int, Intent?> = waitForResult() @@ -2148,9 +2171,9 @@ class RoleManagerMultiUserTest { ) { for (userReference in users().profileGroup(deviceState.initialUser())) { val user = userReference.userHandle() - if (Objects.equals(user, expectedActiveUser)) { - val roleHolders = - roleManager.getRoleHoldersAsUser(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, user) + val roleHolders = + roleManager.getRoleHoldersAsUser(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, user) + if (user == expectedActiveUser) { assertWithMessage( "Expected user ${user.identifier} to have a role holder for " + " $PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME" @@ -2169,9 +2192,7 @@ class RoleManagerMultiUserTest { "Expected user ${user.identifier} to not have a role holder for" + " $PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME" ) - .that( - roleManager.getRoleHoldersAsUser(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, user) - ) + .that(roleHolders) .isEmpty() } } @@ -2183,7 +2204,7 @@ class RoleManagerMultiUserTest { for (userReference in users().profileGroup(deviceState.initialUser())) { val userRoleManager = getRoleManagerForUser(userReference) val user = userReference.userHandle() - if (Objects.equals(user, expectedActiveUser)) { + if (user == expectedActiveUser) { assertWithMessage("Expected default application for user ${user.identifier}") .that( userRoleManager.getDefaultApplication(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME) @@ -2203,7 +2224,7 @@ class RoleManagerMultiUserTest { private fun setDefaultHoldersForTestForAllUsers() { // Set test default role holder. Ensures fallbacks to a default holder for (userRoleManager in - users().profileGroup(deviceState.initialUser()).map { getRoleManagerForUser(it) }) { + users().profileGroup(users().current()).map { getRoleManagerForUser(it) }) { userRoleManager.setDefaultHoldersForTest( PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, listOf(APP_PACKAGE_NAME), @@ -2214,7 +2235,7 @@ class RoleManagerMultiUserTest { private fun clearDefaultHoldersForTestForAllUsers() { // Set test default role holder. Ensures fallbacks to a default holder for (userRoleManager in - users().profileGroup(deviceState.initialUser()).map { getRoleManagerForUser(it) }) { + users().profileGroup(users().current()).map { getRoleManagerForUser(it) }) { userRoleManager.setDefaultHoldersForTest( PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, emptyList(), @@ -2225,7 +2246,7 @@ class RoleManagerMultiUserTest { private fun setRoleVisibleForTestForAllUsers() { // Set test default role holder. Ensures fallbacks to a default holder for (userRoleManager in - users().profileGroup(deviceState.initialUser()).map { getRoleManagerForUser(it) }) { + users().profileGroup(users().current()).map { getRoleManagerForUser(it) }) { userRoleManager.setRoleVisibleForTest(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, true) } } @@ -2233,11 +2254,28 @@ class RoleManagerMultiUserTest { private fun clearRoleVisibleForTestForAllUsers() { // Set test default role holder. Ensures fallbacks to a default holder for (userRoleManager in - users().profileGroup(deviceState.initialUser()).map { getRoleManagerForUser(it) }) { + users().profileGroup(users().current()).map { getRoleManagerForUser(it) }) { userRoleManager.setRoleVisibleForTest(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, false) } } + private fun setRoleFallbackEnabledForAllUsers() { + for (userReference in users().profileGroup(users().current())) { + try { + val userRoleManager = getRoleManagerForUser(userReference) + userRoleManager.setRoleFallbackEnabled(PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME, true) + } catch (e: Exception) { + Log.w( + LOG_TAG, + "Encountered error setting fallback enabled for" + + " $PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME@" + + "${userReference.userHandle().identifier}", + e, + ) + } + } + } + private fun getRoleManagerForUser(user: UserReference): RoleManager { val userContext = context().androidContextAsUser(user) return userContext.getSystemService(RoleManager::class.java) @@ -2250,7 +2288,10 @@ class RoleManagerMultiUserTest { } companion object { + private val LOG_TAG = RoleManagerMultiUserTest::class.java.simpleName + private const val TIMEOUT_MILLIS: Long = (15 * 1000).toLong() + private const val IDLE_TIMEOUT_MILLIS: Long = (2 * 1000).toLong() private const val PROFILE_GROUP_EXCLUSIVITY_ROLE_NAME = RoleManager.ROLE_RESERVED_FOR_TESTING_PROFILE_GROUP_EXCLUSIVITY private const val PROFILE_GROUP_EXCLUSIVITY_ROLE_LABEL = diff --git a/tests/cts/safetycenter/AndroidTest.xml b/tests/cts/safetycenter/AndroidTest.xml index 6d8c3069c..ed161f0b6 100644 --- a/tests/cts/safetycenter/AndroidTest.xml +++ b/tests/cts/safetycenter/AndroidTest.xml @@ -47,6 +47,10 @@ <!-- Disable syncing to prevent overwriting flags during testing. --> <option name="run-command" value="device_config set_sync_disabled_for_tests persistent" /> <option name="teardown-command" value="device_config set_sync_disabled_for_tests none" /> + <!-- Belt-and-braces attempt to dismiss keyguard. Tradefed should have already done this + for us, but this is a precaution in an attempt to mitigate b/379620557. --> + <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> + <option name="run-command" value="wm dismiss-keyguard" /> <!-- Dismiss any system dialogs (e.g. crashes, ANR). --> <option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --receiver-foreground" /> </target_preparer> diff --git a/tests/functional/safetycenter/multiusers/AndroidTest.xml b/tests/functional/safetycenter/multiusers/AndroidTest.xml index 20032357a..bfb7fdbf2 100644 --- a/tests/functional/safetycenter/multiusers/AndroidTest.xml +++ b/tests/functional/safetycenter/multiusers/AndroidTest.xml @@ -47,6 +47,10 @@ <!-- Disable syncing to prevent overwriting flags during testing. --> <option name="run-command" value="device_config set_sync_disabled_for_tests persistent" /> <option name="teardown-command" value="device_config set_sync_disabled_for_tests none" /> + <!-- Belt-and-braces attempt to dismiss keyguard. Tradefed should have already done this + for us, but this is a precaution in an attempt to mitigate b/379620557. --> + <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> + <option name="run-command" value="wm dismiss-keyguard" /> <!-- Dismiss any system dialogs (e.g. crashes, ANR). --> <option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --receiver-foreground" /> </target_preparer> diff --git a/tests/functional/safetycenter/safetycenteractivity/AndroidTest.xml b/tests/functional/safetycenter/safetycenteractivity/AndroidTest.xml index a1826653f..ee79dcd2a 100644 --- a/tests/functional/safetycenter/safetycenteractivity/AndroidTest.xml +++ b/tests/functional/safetycenter/safetycenteractivity/AndroidTest.xml @@ -47,6 +47,10 @@ <!-- Disable syncing to prevent overwriting flags during testing. --> <option name="run-command" value="device_config set_sync_disabled_for_tests persistent" /> <option name="teardown-command" value="device_config set_sync_disabled_for_tests none" /> + <!-- Belt-and-braces attempt to dismiss keyguard. Tradefed should have already done this + for us, but this is a precaution in an attempt to mitigate b/379620557. --> + <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> + <option name="run-command" value="wm dismiss-keyguard" /> <!-- Dismiss any system dialogs (e.g. crashes, ANR). --> <option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --receiver-foreground" /> </target_preparer> diff --git a/tests/functional/safetycenter/singleuser/AndroidTest.xml b/tests/functional/safetycenter/singleuser/AndroidTest.xml index af040eb6f..f778ca93e 100644 --- a/tests/functional/safetycenter/singleuser/AndroidTest.xml +++ b/tests/functional/safetycenter/singleuser/AndroidTest.xml @@ -47,8 +47,8 @@ <!-- Disable syncing to prevent overwriting flags during testing. --> <option name="run-command" value="device_config set_sync_disabled_for_tests persistent" /> <option name="teardown-command" value="device_config set_sync_disabled_for_tests none" /> - <!-- TODO(b/379928062): Ensure device not on lockscreen. Reassess when keyguard bug is - closed --> + <!-- Belt-and-braces attempt to dismiss keyguard. Tradefed should have already done this + for us, but this is a precaution in an attempt to mitigate b/379620557. --> <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> <option name="run-command" value="wm dismiss-keyguard" /> <!-- Dismiss any system dialogs (e.g. crashes, ANR). --> diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt index 64db7d47a..f5d230deb 100644 --- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt +++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt @@ -75,6 +75,7 @@ import com.android.safetycenter.internaldata.SafetyCenterIds import com.android.safetycenter.resources.SafetyCenterResourcesApk import com.android.safetycenter.testing.Coroutines.TIMEOUT_LONG import com.android.safetycenter.testing.Coroutines.TIMEOUT_SHORT +import com.android.safetycenter.testing.Coroutines.assertWithTimeout import com.android.safetycenter.testing.Coroutines.waitForWithTimeout import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.dismissSafetyCenterIssueWithPermission import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.getSafetyCenterConfigWithPermission @@ -2356,18 +2357,14 @@ class SafetyCenterManagerTest { groupId = MULTIPLE_SOURCES_GROUP_ID_2, ) ) - waitForWithTimeout(timeout = RESURFACE_TIMEOUT, checkPeriod = RESURFACE_CHECK) { - val hasResurfaced = - safetyCenterManager - .getSafetyCenterDataWithPermission() - .issues - .contains( - safetyCenterTestData.safetyCenterIssueCritical( - SOURCE_ID_5, - groupId = MULTIPLE_SOURCES_GROUP_ID_2, - ) + assertWithTimeout(timeout = RESURFACE_TIMEOUT, checkPeriod = RESURFACE_CHECK) { + assertThat(safetyCenterManager.getSafetyCenterDataWithPermission().issues) + .contains( + safetyCenterTestData.safetyCenterIssueCritical( + SOURCE_ID_5, + groupId = MULTIPLE_SOURCES_GROUP_ID_2, ) - hasResurfaced + ) } } @@ -3986,9 +3983,9 @@ class SafetyCenterManagerTest { companion object { private val RESURFACE_DELAY = Duration.ofMillis(500) - // Wait 3 times the RESURFACE_DELAY before asserting whether an issue has or has not + // Wait 5 times the RESURFACE_DELAY before asserting whether an issue has or has not // resurfaced. Use a constant additive error buffer if we increase the delay considerably. - private val RESURFACE_TIMEOUT = RESURFACE_DELAY.multipliedBy(3) + private val RESURFACE_TIMEOUT = RESURFACE_DELAY.multipliedBy(5) // Check more than once during a RESURFACE_DELAY before asserting whether an issue has or // has not resurfaced. Use a different check logic (focused at the expected resurface time) diff --git a/tests/functional/safetycenter/subpages/AndroidTest.xml b/tests/functional/safetycenter/subpages/AndroidTest.xml index c3245e9d7..ac493841f 100644 --- a/tests/functional/safetycenter/subpages/AndroidTest.xml +++ b/tests/functional/safetycenter/subpages/AndroidTest.xml @@ -47,6 +47,10 @@ <!-- Disable syncing to prevent overwriting flags during testing. --> <option name="run-command" value="device_config set_sync_disabled_for_tests persistent" /> <option name="teardown-command" value="device_config set_sync_disabled_for_tests none" /> + <!-- Belt-and-braces attempt to dismiss keyguard. Tradefed should have already done this + for us, but this is a precaution in an attempt to mitigate b/379620557. --> + <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> + <option name="run-command" value="wm dismiss-keyguard" /> <!-- Dismiss any system dialogs (e.g. crashes, ANR). --> <option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --receiver-foreground" /> </target_preparer> diff --git a/tests/hostside/safetycenter/AndroidTest.xml b/tests/hostside/safetycenter/AndroidTest.xml index a28b70c3c..41f0bcc40 100644 --- a/tests/hostside/safetycenter/AndroidTest.xml +++ b/tests/hostside/safetycenter/AndroidTest.xml @@ -32,6 +32,10 @@ <!-- Disable syncing to prevent overwriting flags during testing. --> <option name="run-command" value="device_config set_sync_disabled_for_tests persistent" /> <option name="teardown-command" value="device_config set_sync_disabled_for_tests none" /> + <!-- Belt-and-braces attempt to dismiss keyguard. Tradefed should have already done this + for us, but this is a precaution in an attempt to mitigate b/379620557. --> + <option name="run-command" value="input keyevent KEYCODE_WAKEUP" /> + <option name="run-command" value="wm dismiss-keyguard" /> <!-- Dismiss any system dialogs (e.g. crashes, ANR). --> <option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --receiver-foreground" /> </target_preparer> diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt index 60e6e41ec..c56c913b6 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt @@ -69,6 +69,12 @@ class SafetyCenterNotificationLoggingHelperTests { @Test fun sendNotification() { safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, newTestDataWithNotifiableIssue()) + TestNotificationListener.waitForSingleNotificationMatching( + NotificationCharacteristics( + actions = listOf("See issue"), + safetySourceId = SINGLE_SOURCE_ID, + ) + ) } @Test @@ -104,7 +110,7 @@ class SafetyCenterNotificationLoggingHelperTests { statusBarNotificationWithChannel.statusBarNotification.notification.contentIntent SafetyCenterActivityLauncher.executeBlockAndExit( launchActivity = { PendingIntentSender.send(contentIntent) }, - block = {} // No action required + block = {}, // No action required ) } } diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt index cc8c53d5e..47f5165e2 100644 --- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt +++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt @@ -22,6 +22,7 @@ import java.time.Duration import kotlinx.coroutines.DEBUG_PROPERTY_NAME import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_AUTO import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON +import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeout @@ -68,6 +69,20 @@ object Coroutines { runBlockingWithTimeout(timeout) { waitFor(checkPeriod, condition) } } + /** Check an assertion passes, with a timeout if it does not. */ + fun assertWithTimeout( + timeout: Duration = TIMEOUT_LONG, + checkPeriod: Duration = CHECK_PERIOD, + assertion: () -> Unit, + ) { + try { + runBlockingWithTimeout(timeout) { assertThatWaiting(checkPeriod, assertion) } + } catch (ex: TimeoutCancellationException) { + // Rerun the assertion to generate a meaningful error message that isn't just "timeout" + assertion() + } + } + /** Retries a [fallibleAction] until no errors are thrown or a timeout occurs. */ fun waitForSuccessWithTimeout( timeout: Duration = TIMEOUT_LONG, @@ -105,6 +120,21 @@ object Coroutines { } } + /** Check an assertion passes using coroutines. */ + private suspend fun assertThatWaiting( + checkPeriod: Duration = CHECK_PERIOD, + assertion: () -> Unit, + ) { + while (true) { + try { + assertion() + break + } catch (ex: AssertionError) { + delay(checkPeriod.toMillis()) + } + } + } + private const val TAG: String = "Coroutines" /** A medium period, to be used for conditions that are expected to change. */ |