Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-qpr-dev
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 2a3f916..e8e5a51 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1970,8 +1970,8 @@
<string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"Presiona para ver archivos"</string>
<string name="pin_target" msgid="8036028973110156895">"Fijar"</string>
<string name="pin_specific_target" msgid="7824671240625957415">"Fijar <xliff:g id="LABEL">%1$s</xliff:g>"</string>
- <string name="unpin_target" msgid="3963318576590204447">"No fijar"</string>
- <string name="unpin_specific_target" msgid="3859828252160908146">"No fijar <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <string name="unpin_target" msgid="3963318576590204447">"Dejar de fijar"</string>
+ <string name="unpin_specific_target" msgid="3859828252160908146">"Dejar de fijar <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="app_info" msgid="6113278084877079851">"Información de apps"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Iniciando demostración…"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 79faaac..0daa324 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1139,7 +1139,7 @@
<string name="copy" msgid="5472512047143665218">"कॉपी करें"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"क्लिपबोर्ड पर कॉपी नहीं हो सका"</string>
<string name="paste" msgid="461843306215520225">"चिपकाएं"</string>
- <string name="paste_as_plain_text" msgid="7664800665823182587">"सादे पाठ के रूप में चिपकाएं"</string>
+ <string name="paste_as_plain_text" msgid="7664800665823182587">"सादे टेक्स्ट के रूप में चिपकाएं"</string>
<string name="replace" msgid="7842675434546657444">"बदलें•"</string>
<string name="delete" msgid="1514113991712129054">"मिटाएं"</string>
<string name="copyUrl" msgid="6229645005987260230">"यूआरएल को कॉपी करें"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 9ab64e6..d11eca6 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -252,7 +252,7 @@
<string name="bugreport_message" msgid="5212529146119624326">"현재 기기 상태에 대한 정보를 수집하여 이메일 메시지로 전송합니다. 버그 신고를 시작하여 전송할 준비가 되려면 약간 시간이 걸립니다."</string>
<string name="bugreport_option_interactive_title" msgid="7968287837902871289">"대화형 보고서"</string>
<string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"대부분의 경우 이 옵션을 사용합니다. 신고 진행 상황을 추적하고 문제에 대한 세부정보를 입력하고 스크린샷을 찍을 수 있습니다. 신고하기에 시간이 너무 오래 걸리고 사용 빈도가 낮은 일부 섹션을 생략할 수 있습니다."</string>
- <string name="bugreport_option_full_title" msgid="7681035745950045690">"전체 보고서"</string>
+ <string name="bugreport_option_full_title" msgid="7681035745950045690">"전체 신고"</string>
<string name="bugreport_option_full_summary" msgid="1975130009258435885">"기기가 응답하지 않거나 너무 느리거나 모든 보고서 섹션이 필요한 경우 이 옵션을 사용하여 시스템 방해를 최소화합니다. 세부정보를 추가하거나 스크린샷을 추가로 찍을 수 없습니다."</string>
<string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{버그 신고 스크린샷을 #초 후에 찍습니다.}other{버그 신고 스크린샷을 #초 후에 찍습니다.}}"</string>
<string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"버그 신고용 스크린샷 촬영 완료"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 0fdfed8..17b1d1b 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"አስፋ"</string>
<string name="minimize_button_text" msgid="271592547935841753">"አሳንስ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"ተመለስ"</string>
+ <string name="handle_text" msgid="1766582106752184456">"መያዣ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 351e192..2babc3e 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"تكبير"</string>
<string name="minimize_button_text" msgid="271592547935841753">"تصغير"</string>
<string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"رجوع"</string>
+ <string name="handle_text" msgid="1766582106752184456">"مقبض"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 765aaba..fe43cd6 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string>
<string name="minimize_button_text" msgid="271592547935841753">"মিনিমাইজ কৰক"</string>
<string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"উভতি যাওক"</string>
+ <string name="handle_text" msgid="1766582106752184456">"হেণ্ডেল"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 0ec5db1..c22f542 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Böyüdün"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Kiçildin"</string>
<string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Geriyə"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Hər kəsə açıq istifadəçi adı"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index bd4a079..cf5394b 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Разгарнуць"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Згарнуць"</string>
<string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index a04a50d..c525f52 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Увеличаване"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Намаляване"</string>
<string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Манипулатор"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 2cc0ab3..bec284d 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -84,6 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziranje"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimiziranje"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string>
- <string name="back_button_text" msgid="1469718707134137085">"Natrag"</string>
- <string name="handle_text" msgid="1766582106752184456">"Pokazivač"</string>
+ <string name="back_button_text" msgid="1469718707134137085">"Nazad"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index a2badaf..c84bb48 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maximitza"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimitza"</string>
<string name="close_button_text" msgid="2913281996024033299">"Tanca"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Enrere"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Ansa"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 084ea86..60c1f85 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimér"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string>
<string name="close_button_text" msgid="2913281996024033299">"Luk"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Tilbage"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Håndtag"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 195c335..b57f0c8 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maximieren"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimieren"</string>
<string name="close_button_text" msgid="2913281996024033299">"Schließen"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Zurück"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Ziehpunkt"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 0ad387b..aed03ac 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 4b85a22..bddc2c3 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index cc90578..696a520 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimeeri"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimeeri"</string>
<string name="close_button_text" msgid="2913281996024033299">"Sule"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Tagasi"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Käepide"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index a1d0b58..7550a09 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string>
<string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string>
<string name="close_button_text" msgid="2913281996024033299">"بستن"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"برگشتن"</string>
+ <string name="handle_text" msgid="1766582106752184456">"دستگیره"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 5df1e04..a79adf8 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Suurenna"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Pienennä"</string>
<string name="close_button_text" msgid="2913281996024033299">"Sulje"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Takaisin"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Kahva"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index c4b386a..865e2dc 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string>
<string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Poignée"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index f5a106d..47e6696 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
<string name="close_button_text" msgid="2913281996024033299">"Pechar"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Atrás"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Controlador"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 95484d5..2c643de 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"बड़ा करें"</string>
<string name="minimize_button_text" msgid="271592547935841753">"विंडो छोटी करें"</string>
<string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"वापस जाएं"</string>
+ <string name="handle_text" msgid="1766582106752184456">"हैंडल"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 5ae72eb..d3bca33 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Ծավալել"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Ծալել"</string>
<string name="close_button_text" msgid="2913281996024033299">"Փակել"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Հետ"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Նշիչ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index d36a83f..f157fcf 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimalkan"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimalkan"</string>
<string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Kembali"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Tuas"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 31d483e..ead1757 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Stækka"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minnka"</string>
<string name="close_button_text" msgid="2913281996024033299">"Loka"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Til baka"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Handfang"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 5c9425e..12c962d 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"הגדלה"</string>
<string name="minimize_button_text" msgid="271592547935841753">"מזעור"</string>
<string name="close_button_text" msgid="2913281996024033299">"סגירה"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"חזרה"</string>
+ <string name="handle_text" msgid="1766582106752184456">"נקודת אחיזה"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 787ac3e..b284361 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"მაქსიმალურად გაშლა"</string>
<string name="minimize_button_text" msgid="271592547935841753">"ჩაკეცვა"</string>
<string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"უკან"</string>
+ <string name="handle_text" msgid="1766582106752184456">"იდენტიფიკატორი"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 927f0d7..2d842b8 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Жаю"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Кішірейту"</string>
<string name="close_button_text" msgid="2913281996024033299">"Жабу"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Артқа"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Идентификатор"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 955b2f8..3243a64 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"ពង្រីក"</string>
<string name="minimize_button_text" msgid="271592547935841753">"បង្រួម"</string>
<string name="close_button_text" msgid="2913281996024033299">"បិទ"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"ថយក្រោយ"</string>
+ <string name="handle_text" msgid="1766582106752184456">"ឈ្មោះអ្នកប្រើប្រាស់"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index a69e105..3a655b8 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"최대화"</string>
<string name="minimize_button_text" msgid="271592547935841753">"최소화"</string>
<string name="close_button_text" msgid="2913281996024033299">"닫기"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"뒤로"</string>
+ <string name="handle_text" msgid="1766582106752184456">"핸들"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 15bde88..b800e3e 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"ຂະຫຍາຍໃຫຍ່ສຸດ"</string>
<string name="minimize_button_text" msgid="271592547935841753">"ຫຍໍ້ລົງ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"ກັບຄືນ"</string>
+ <string name="handle_text" msgid="1766582106752184456">"ມືບັງຄັບ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 275efa2..94339a4 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Padidinti"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Sumažinti"</string>
<string name="close_button_text" msgid="2913281996024033299">"Uždaryti"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Atgal"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Rankenėlė"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 3048630..d282453 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimizēt"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimizēt"</string>
<string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Atpakaļ"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Turis"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 9013828..5db8d6d 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"വലുതാക്കുക"</string>
<string name="minimize_button_text" msgid="271592547935841753">"ചെറുതാക്കുക"</string>
<string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"മടങ്ങുക"</string>
+ <string name="handle_text" msgid="1766582106752184456">"ഹാൻഡിൽ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index dc884e9..779cf5c 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"मोठे करा"</string>
<string name="minimize_button_text" msgid="271592547935841753">"लहान करा"</string>
<string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"मागे जा"</string>
+ <string name="handle_text" msgid="1766582106752184456">"हँडल"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index a2f24f2..0ceee2d 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimer"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string>
<string name="close_button_text" msgid="2913281996024033299">"Lukk"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Tilbake"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Håndtak"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 6a70d8d..7ba49e5 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"ठुलो बनाउनुहोस्"</string>
<string name="minimize_button_text" msgid="271592547935841753">"मिनिमाइज गर्नुहोस्"</string>
<string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"पछाडि"</string>
+ <string name="handle_text" msgid="1766582106752184456">"ह्यान्डल"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index d1d7db8..dd3ebe4 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maximaliseren"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimaliseren"</string>
<string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Terug"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Gebruikersnaam"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index d2a96d9..c3056ca 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"ਵੱਡਾ ਕਰੋ"</string>
<string name="minimize_button_text" msgid="271592547935841753">"ਛੋਟਾ ਕਰੋ"</string>
<string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"ਪਿੱਛੇ"</string>
+ <string name="handle_text" msgid="1766582106752184456">"ਹੈਂਡਲ"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index cc2b2c3..56a6fb1 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksymalizuj"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimalizuj"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Wstecz"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Uchwyt"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 98a775e..b96caf2 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Развернуть"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Свернуть"</string>
<string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 5724061..a1ec3b5 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"විහිදන්න"</string>
<string name="minimize_button_text" msgid="271592547935841753">"කුඩා කරන්න"</string>
<string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"ආපසු"</string>
+ <string name="handle_text" msgid="1766582106752184456">"හැඬලය"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 12f022e..2f995e5 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimiraj"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimiraj"</string>
<string name="close_button_text" msgid="2913281996024033299">"Zapri"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Nazaj"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Ročica"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index cdd8706..3d9bde4 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Maksimizo"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimizo"</string>
<string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Pas"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Emërtimi"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index fef3792..b39fd04 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Utöka"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Minimera"</string>
<string name="close_button_text" msgid="2913281996024033299">"Stäng"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Tillbaka"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Handtag"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 2d10e20..f4d4cee 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Panua"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Punguza"</string>
<string name="close_button_text" msgid="2913281996024033299">"Funga"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Rudi nyuma"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Ncha"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 0eeeca7..6d050c2 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"பெரிதாக்கும்"</string>
<string name="minimize_button_text" msgid="271592547935841753">"சிறிதாக்கும்"</string>
<string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"பின்செல்லும்"</string>
+ <string name="handle_text" msgid="1766582106752184456">"ஹேண்டில்"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 2b105bdb..025e2e6 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Ekranı Kapla"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Küçült"</string>
<string name="close_button_text" msgid="2913281996024033299">"Kapat"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Geri"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Herkese açık kullanıcı adı"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index a092531..97bb680 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Збільшити"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Згорнути"</string>
<string name="close_button_text" msgid="2913281996024033299">"Закрити"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Назад"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Маркер"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 0330125..ce73bd5 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Yoyish"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Kichraytirish"</string>
<string name="close_button_text" msgid="2913281996024033299">"Yopish"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Orqaga"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Identifikator"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 6e4a768..511db6f 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"Phóng to"</string>
<string name="minimize_button_text" msgid="271592547935841753">"Thu nhỏ"</string>
<string name="close_button_text" msgid="2913281996024033299">"Đóng"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"Quay lại"</string>
+ <string name="handle_text" msgid="1766582106752184456">"Xử lý"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index df911ed..16cbf12 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -84,8 +84,6 @@
<string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
<string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
<string name="close_button_text" msgid="2913281996024033299">"关闭"</string>
- <!-- no translation found for back_button_text (1469718707134137085) -->
- <skip />
- <!-- no translation found for handle_text (1766582106752184456) -->
- <skip />
+ <string name="back_button_text" msgid="1469718707134137085">"返回"</string>
+ <string name="handle_text" msgid="1766582106752184456">"处理"</string>
</resources>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index f484022..59d87a0 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -19,7 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="pip_phone_close" msgid="5783752637260411309">"Vala"</string>
<string name="pip_phone_expand" msgid="2579292903468287504">"Nweba"</string>
- <string name="pip_phone_settings" msgid="5468987116750491918">"Izilungiselelo"</string>
+ <string name="pip_phone_settings" msgid="5468987116750491918">"Amasethingi"</string>
<string name="pip_phone_enter_split" msgid="7042877263880641911">"Faka ukuhlukanisa isikrini"</string>
<string name="pip_menu_title" msgid="5393619322111827096">"Imenyu"</string>
<string name="pip_notification_title" msgid="1347104727641353453">"U-<xliff:g id="NAME">%s</xliff:g> ungaphakathi kwesithombe esiphakathi kwesithombe"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
index e903897..f209521 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
@@ -33,6 +33,8 @@
// This class is orientation-agnostic, so we compute both for later use
public final float topTaskPercent;
public final float leftTaskPercent;
+ public final float dividerWidthPercent;
+ public final float dividerHeightPercent;
/**
* If {@code true}, that means at the time of creation of this object, the
* split-screened apps were vertically stacked. This is useful in scenarios like
@@ -62,8 +64,12 @@
appsStackedVertically = false;
}
- leftTaskPercent = this.leftTopBounds.width() / (float) rightBottomBounds.right;
- topTaskPercent = this.leftTopBounds.height() / (float) rightBottomBounds.bottom;
+ float totalWidth = rightBottomBounds.right - leftTopBounds.left;
+ float totalHeight = rightBottomBounds.bottom - leftTopBounds.top;
+ leftTaskPercent = leftTopBounds.width() / totalWidth;
+ topTaskPercent = leftTopBounds.height() / totalHeight;
+ dividerWidthPercent = visualDividerBounds.width() / totalWidth;
+ dividerHeightPercent = visualDividerBounds.height() / totalHeight;
}
public SplitBounds(Parcel parcel) {
@@ -75,6 +81,8 @@
appsStackedVertically = parcel.readBoolean();
leftTopTaskId = parcel.readInt();
rightBottomTaskId = parcel.readInt();
+ dividerWidthPercent = parcel.readInt();
+ dividerHeightPercent = parcel.readInt();
}
@Override
@@ -87,6 +95,8 @@
parcel.writeBoolean(appsStackedVertically);
parcel.writeInt(leftTopTaskId);
parcel.writeInt(rightBottomTaskId);
+ parcel.writeFloat(dividerWidthPercent);
+ parcel.writeFloat(dividerHeightPercent);
}
@Override
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 18b8ca9..77dfbee 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4470785958457506021">"隨附裝置管理員"</string>
+ <string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string>
<string name="confirmation_title" msgid="3785000297483688997">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>"</string>
<string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
<string name="chooser_title" msgid="2262294130493605839">"選擇要讓「<xliff:g id="APP_NAME">%2$s</xliff:g>」<strong></strong>管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index ca36fa4..fdfad2b 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -25,7 +25,6 @@
import android.os.Looper
import android.util.Log
import android.util.MathUtils
-import android.view.GhostView
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
@@ -86,6 +85,9 @@
*/
val sourceIdentity: Any
+ /** The CUJ associated to this controller. */
+ val cuj: DialogCuj?
+
/**
* Move the drawing of the source in the overlay of [viewGroup].
*
@@ -142,7 +144,31 @@
* controlled by this controller.
*/
// TODO(b/252723237): Make this non-nullable
- fun jankConfigurationBuilder(cuj: Int): InteractionJankMonitor.Configuration.Builder?
+ fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder?
+
+ companion object {
+ /**
+ * Create a [Controller] that can animate [source] to and from a dialog.
+ *
+ * Important: The view must be attached to a [ViewGroup] when calling this function and
+ * during the animation. For safety, this method will return null when it is not.
+ *
+ * Note: The background of [view] should be a (rounded) rectangle so that it can be
+ * properly animated.
+ */
+ fun fromView(source: View, cuj: DialogCuj? = null): Controller? {
+ if (source.parent !is ViewGroup) {
+ Log.e(
+ TAG,
+ "Skipping animation as view $source is not attached to a ViewGroup",
+ Exception(),
+ )
+ return null
+ }
+
+ return ViewDialogLaunchAnimatorController(source, cuj)
+ }
+ }
}
/**
@@ -172,7 +198,12 @@
cuj: DialogCuj? = null,
animateBackgroundBoundsChange: Boolean = false
) {
- show(dialog, createController(view), cuj, animateBackgroundBoundsChange)
+ val controller = Controller.fromView(view, cuj)
+ if (controller == null) {
+ dialog.show()
+ } else {
+ show(dialog, controller, animateBackgroundBoundsChange)
+ }
}
/**
@@ -187,10 +218,10 @@
* Caveats: When calling this function and [dialog] is not a fullscreen dialog, then it will be
* made fullscreen and 2 views will be inserted between the dialog DecorView and its children.
*/
+ @JvmOverloads
fun show(
dialog: Dialog,
controller: Controller,
- cuj: DialogCuj? = null,
animateBackgroundBoundsChange: Boolean = false
) {
if (Looper.myLooper() != Looper.getMainLooper()) {
@@ -207,7 +238,10 @@
it.dialog.window.decorView.viewRootImpl == controller.viewRoot
}
val animateFrom =
- animatedParent?.dialogContentWithBackground?.let { createController(it) } ?: controller
+ animatedParent?.dialogContentWithBackground?.let {
+ Controller.fromView(it, controller.cuj)
+ }
+ ?: controller
if (animatedParent == null && animateFrom !is LaunchableView) {
// Make sure the View we launch from implements LaunchableView to avoid visibility
@@ -244,96 +278,12 @@
animateBackgroundBoundsChange,
animatedParent,
isForTesting,
- cuj,
)
openedDialogs.add(animatedDialog)
animatedDialog.start()
}
- /** Create a [Controller] that can animate [source] to & from a dialog. */
- private fun createController(source: View): Controller {
- return object : Controller {
- override val viewRoot: ViewRootImpl
- get() = source.viewRootImpl
-
- override val sourceIdentity: Any = source
-
- override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
- // Create a temporary ghost of the source (which will make it invisible) and add it
- // to the host dialog.
- GhostView.addGhost(source, viewGroup)
-
- // The ghost of the source was just created, so the source is currently invisible.
- // We need to make sure that it stays invisible as long as the dialog is shown or
- // animating.
- (source as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
- }
-
- override fun stopDrawingInOverlay() {
- // Note: here we should remove the ghost from the overlay, but in practice this is
- // already done by the launch controllers created below.
-
- // Make sure we allow the source to change its visibility again.
- (source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
- source.visibility = View.VISIBLE
- }
-
- override fun createLaunchController(): LaunchAnimator.Controller {
- val delegate = GhostedViewLaunchAnimatorController(source)
- return object : LaunchAnimator.Controller by delegate {
- override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
- // Remove the temporary ghost added by [startDrawingInOverlayOf]. Another
- // ghost (that ghosts only the source content, and not its background) will
- // be added right after this by the delegate and will be animated.
- GhostView.removeGhost(source)
- delegate.onLaunchAnimationStart(isExpandingFullyAbove)
- }
-
- override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
- delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
-
- // We hide the source when the dialog is showing. We will make this view
- // visible again when dismissing the dialog. This does nothing if the source
- // implements [LaunchableView], as it's already INVISIBLE in that case.
- source.visibility = View.INVISIBLE
- }
- }
- }
-
- override fun createExitController(): LaunchAnimator.Controller {
- return GhostedViewLaunchAnimatorController(source)
- }
-
- override fun shouldAnimateExit(): Boolean {
- // The source should be invisible by now, if it's not then something else changed
- // its visibility and we probably don't want to run the animation.
- if (source.visibility != View.INVISIBLE) {
- return false
- }
-
- return source.isAttachedToWindow && ((source.parent as? View)?.isShown ?: true)
- }
-
- override fun onExitAnimationCancelled() {
- // Make sure we allow the source to change its visibility again.
- (source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
-
- // If the view is invisible it's probably because of us, so we make it visible
- // again.
- if (source.visibility == View.INVISIBLE) {
- source.visibility = View.VISIBLE
- }
- }
-
- override fun jankConfigurationBuilder(
- cuj: Int
- ): InteractionJankMonitor.Configuration.Builder? {
- return InteractionJankMonitor.Configuration.Builder.withView(cuj, source)
- }
- }
- }
-
/**
* Launch [dialog] from [another dialog][animateFrom] that was shown using [show]. This will
* allow for dismissing the whole stack.
@@ -563,9 +513,6 @@
* Whether synchronization should be disabled, which can be useful if we are running in a test.
*/
private val forceDisableSynchronization: Boolean,
-
- /** Interaction to which the dialog animation is associated. */
- private val cuj: DialogCuj? = null
) {
/**
* The DecorView of this dialog window.
@@ -618,8 +565,9 @@
private var hasInstrumentedJank = false
fun start() {
+ val cuj = controller.cuj
if (cuj != null) {
- val config = controller.jankConfigurationBuilder(cuj.cujType)
+ val config = controller.jankConfigurationBuilder()
if (config != null) {
if (cuj.tag != null) {
config.setTag(cuj.tag)
@@ -917,7 +865,7 @@
}
if (hasInstrumentedJank) {
- interactionJankMonitor.end(cuj!!.cujType)
+ interactionJankMonitor.end(controller.cuj!!.cujType)
}
}
)
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt
index 8ce372d..40a5e97 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt
@@ -30,7 +30,12 @@
*/
fun activityLaunchController(cujType: Int? = null): ActivityLaunchAnimator.Controller?
- // TODO(b/230830644): Introduce DialogLaunchAnimator and a function to expose it here.
+ /**
+ * Create a [DialogLaunchAnimator.Controller] that can be used to expand this [Expandable] into
+ * a Dialog, or return `null` if this [Expandable] should not be animated (e.g. if it is
+ * currently not attached or visible).
+ */
+ fun dialogLaunchController(cuj: DialogCuj? = null): DialogLaunchAnimator.Controller?
companion object {
/**
@@ -39,6 +44,7 @@
* Note: The background of [view] should be a (rounded) rectangle so that it can be properly
* animated.
*/
+ @JvmStatic
fun fromView(view: View): Expandable {
return object : Expandable {
override fun activityLaunchController(
@@ -46,6 +52,12 @@
): ActivityLaunchAnimator.Controller? {
return ActivityLaunchAnimator.Controller.fromView(view, cujType)
}
+
+ override fun dialogLaunchController(
+ cuj: DialogCuj?
+ ): DialogLaunchAnimator.Controller? {
+ return DialogLaunchAnimator.Controller.fromView(view, cuj)
+ }
}
}
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
new file mode 100644
index 0000000..ecee598
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.systemui.animation
+
+import android.view.GhostView
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewRootImpl
+import com.android.internal.jank.InteractionJankMonitor
+
+/** A [DialogLaunchAnimator.Controller] that can animate a [View] from/to a dialog. */
+class ViewDialogLaunchAnimatorController
+internal constructor(
+ private val source: View,
+ override val cuj: DialogCuj?,
+) : DialogLaunchAnimator.Controller {
+ override val viewRoot: ViewRootImpl
+ get() = source.viewRootImpl
+
+ override val sourceIdentity: Any = source
+
+ override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
+ // Create a temporary ghost of the source (which will make it invisible) and add it
+ // to the host dialog.
+ GhostView.addGhost(source, viewGroup)
+
+ // The ghost of the source was just created, so the source is currently invisible.
+ // We need to make sure that it stays invisible as long as the dialog is shown or
+ // animating.
+ (source as? LaunchableView)?.setShouldBlockVisibilityChanges(true)
+ }
+
+ override fun stopDrawingInOverlay() {
+ // Note: here we should remove the ghost from the overlay, but in practice this is
+ // already done by the launch controllers created below.
+
+ // Make sure we allow the source to change its visibility again.
+ (source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
+ source.visibility = View.VISIBLE
+ }
+
+ override fun createLaunchController(): LaunchAnimator.Controller {
+ val delegate = GhostedViewLaunchAnimatorController(source)
+ return object : LaunchAnimator.Controller by delegate {
+ override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
+ // Remove the temporary ghost added by [startDrawingInOverlayOf]. Another
+ // ghost (that ghosts only the source content, and not its background) will
+ // be added right after this by the delegate and will be animated.
+ GhostView.removeGhost(source)
+ delegate.onLaunchAnimationStart(isExpandingFullyAbove)
+ }
+
+ override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+ delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
+
+ // We hide the source when the dialog is showing. We will make this view
+ // visible again when dismissing the dialog. This does nothing if the source
+ // implements [LaunchableView], as it's already INVISIBLE in that case.
+ source.visibility = View.INVISIBLE
+ }
+ }
+ }
+
+ override fun createExitController(): LaunchAnimator.Controller {
+ return GhostedViewLaunchAnimatorController(source)
+ }
+
+ override fun shouldAnimateExit(): Boolean {
+ // The source should be invisible by now, if it's not then something else changed
+ // its visibility and we probably don't want to run the animation.
+ if (source.visibility != View.INVISIBLE) {
+ return false
+ }
+
+ return source.isAttachedToWindow && ((source.parent as? View)?.isShown ?: true)
+ }
+
+ override fun onExitAnimationCancelled() {
+ // Make sure we allow the source to change its visibility again.
+ (source as? LaunchableView)?.setShouldBlockVisibilityChanges(false)
+
+ // If the view is invisible it's probably because of us, so we make it visible
+ // again.
+ if (source.visibility == View.INVISIBLE) {
+ source.visibility = View.VISIBLE
+ }
+ }
+
+ override fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder? {
+ val type = cuj?.cujType ?: return null
+ return InteractionJankMonitor.Configuration.Builder.withView(type, source)
+ }
+}
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 8457312..cf66ff6 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -40,6 +40,10 @@
"tests/**/*.kt",
"tests/**/*.java",
],
+ data: [
+ ":framework",
+ ":androidx.annotation_annotation",
+ ],
static_libs: [
"SystemUILintChecker",
"junit",
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt
index 4eeeb85..4b9aa13 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt
@@ -32,7 +32,8 @@
class SoftwareBitmapDetector : Detector(), SourceCodeScanner {
override fun getApplicableReferenceNames(): List<String> {
- return mutableListOf("ALPHA_8", "RGB_565", "ARGB_8888", "RGBA_F16", "RGBA_1010102")
+ return mutableListOf(
+ "ALPHA_8", "RGB_565", "ARGB_4444", "ARGB_8888", "RGBA_F16", "RGBA_1010102")
}
override fun visitReference(
@@ -40,13 +41,12 @@
reference: UReferenceExpression,
referenced: PsiElement
) {
-
val evaluator = context.evaluator
if (evaluator.isMemberInClass(referenced as? PsiField, "android.graphics.Bitmap.Config")) {
context.report(
ISSUE,
referenced,
- context.getNameLocation(referenced),
+ context.getNameLocation(reference),
"Replace software bitmap with `Config.HARDWARE`"
)
}
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt
index d4c55c0..141dd05 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/AndroidStubs.kt
@@ -18,185 +18,22 @@
import com.android.annotations.NonNull
import com.android.tools.lint.checks.infrastructure.LintDetectorTest.java
+import com.android.tools.lint.checks.infrastructure.TestFiles.LibraryReferenceTestFile
+import java.io.File
import org.intellij.lang.annotations.Language
@Suppress("UnstableApiUsage")
@NonNull
private fun indentedJava(@NonNull @Language("JAVA") source: String) = java(source).indented()
-internal val commonSettingsCode =
- """
-public static float getFloat(ContentResolver cr, String name) { return 0.0f; }
-public static long getLong(ContentResolver cr, String name) {
- return 0L;
-}
-public static int getInt(ContentResolver cr, String name) {
- return 0;
-}
-public static String getString(ContentResolver cr, String name) {
- return "";
-}
-public static float getFloat(ContentResolver cr, String name, float def) {
- return 0.0f;
-}
-public static long getLong(ContentResolver cr, String name, long def) {
- return 0L;
-}
-public static int getInt(ContentResolver cr, String name, int def) {
- return 0;
-}
-public static String getString(ContentResolver cr, String name, String def) {
- return "";
-}
-public static boolean putFloat(ContentResolver cr, String name, float value) {
- return true;
-}
-public static boolean putLong(ContentResolver cr, String name, long value) {
- return true;
-}
-public static boolean putInt(ContentResolver cr, String name, int value) {
- return true;
-}
-public static boolean putFloat(ContentResolver cr, String name) {
- return true;
-}
-public static boolean putString(ContentResolver cr, String name, String value) {
- return true;
-}
-"""
-
/*
* This file contains stubs of framework APIs and System UI classes for testing purposes only. The
* stubs are not used in the lint detectors themselves.
*/
internal val androidStubs =
arrayOf(
- indentedJava(
- """
-package android.app;
-
-public class ActivityManager {
- public static int getCurrentUser() {}
-}
-"""
- ),
- indentedJava(
- """
-package android.accounts;
-
-public class AccountManager {
- public static AccountManager get(Context context) { return null; }
-}
-"""
- ),
- indentedJava(
- """
-package android.os;
-import android.content.pm.UserInfo;
-import android.annotation.UserIdInt;
-
-public class UserManager {
- public UserInfo getUserInfo(@UserIdInt int userId) {}
-}
-"""
- ),
- indentedJava("""
-package android.annotation;
-
-public @interface UserIdInt {}
-"""),
- indentedJava("""
-package android.content.pm;
-
-public class UserInfo {}
-"""),
- indentedJava("""
-package android.os;
-
-public class Looper {}
-"""),
- indentedJava("""
-package android.os;
-
-public class Handler {}
-"""),
- indentedJava("""
-package android.content;
-
-public class ServiceConnection {}
-"""),
- indentedJava("""
-package android.os;
-
-public enum UserHandle {
- ALL
-}
-"""),
- indentedJava(
- """
-package android.content;
-import android.os.UserHandle;
-import android.os.Handler;
-import android.os.Looper;
-import java.util.concurrent.Executor;
-
-public class Context {
- public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {}
- public void registerReceiverAsUser(
- BroadcastReceiver receiver, UserHandle user, IntentFilter filter,
- String broadcastPermission, Handler scheduler) {}
- public void registerReceiverForAllUsers(
- BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission,
- Handler scheduler) {}
- public void sendBroadcast(Intent intent) {}
- public void sendBroadcast(Intent intent, String receiverPermission) {}
- public void sendBroadcastAsUser(Intent intent, UserHandle userHandle, String permission) {}
- public void bindService(Intent intent) {}
- public void bindServiceAsUser(
- Intent intent, ServiceConnection connection, int flags, UserHandle userHandle) {}
- public void unbindService(ServiceConnection connection) {}
- public Looper getMainLooper() { return null; }
- public Executor getMainExecutor() { return null; }
- public Handler getMainThreadHandler() { return null; }
- public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) { return null; }
- public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);
-}
-"""
- ),
- indentedJava(
- """
-package android.app;
-import android.content.Context;
-
-public class Activity extends Context {}
-"""
- ),
- indentedJava(
- """
-package android.graphics;
-
-public class Bitmap {
- public enum Config {
- ARGB_8888,
- RGB_565,
- HARDWARE
- }
- public static Bitmap createBitmap(int width, int height, Config config) {
- return null;
- }
-}
-"""
- ),
- indentedJava("""
-package android.content;
-
-public class BroadcastReceiver {}
-"""),
- indentedJava("""
-package android.content;
-
-public class IntentFilter {}
-"""),
+ LibraryReferenceTestFile(File("framework.jar").canonicalFile),
+ LibraryReferenceTestFile(File("androidx.annotation_annotation.jar").canonicalFile),
indentedJava(
"""
package com.android.systemui.settings;
@@ -208,47 +45,4 @@
}
"""
),
- indentedJava(
- """
-package androidx.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface WorkerThread {
-}
-"""
- ),
- indentedJava(
- """
-package android.provider;
-
-public class Settings {
- public static final class Global {
- public static final String UNLOCK_SOUND = "unlock_sound";
- """ +
- commonSettingsCode +
- """
- }
- public static final class Secure {
- """ +
- commonSettingsCode +
- """
- }
- public static final class System {
- """ +
- commonSettingsCode +
- """
- }
-}
-"""
- ),
)
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SoftwareBitmapDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SoftwareBitmapDetectorTest.kt
index 090ddf8..c632636 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SoftwareBitmapDetectorTest.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SoftwareBitmapDetectorTest.kt
@@ -51,12 +51,12 @@
.run()
.expect(
"""
- src/android/graphics/Bitmap.java:5: Warning: Replace software bitmap with Config.HARDWARE [SoftwareBitmap]
- ARGB_8888,
- ~~~~~~~~~
- src/android/graphics/Bitmap.java:6: Warning: Replace software bitmap with Config.HARDWARE [SoftwareBitmap]
- RGB_565,
- ~~~~~~~
+ src/TestClass.java:5: Warning: Replace software bitmap with Config.HARDWARE [SoftwareBitmap]
+ Bitmap.createBitmap(300, 300, Bitmap.Config.RGB_565);
+ ~~~~~~~
+ src/TestClass.java:6: Warning: Replace software bitmap with Config.HARDWARE [SoftwareBitmap]
+ Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
+ ~~~~~~~~~
0 errors, 2 warnings
"""
)
@@ -67,7 +67,7 @@
lint()
.files(
TestFiles.java(
- """
+ """
import android.graphics.Bitmap;
public class TestClass {
@@ -76,8 +76,7 @@
}
}
"""
- )
- .indented(),
+ ),
*stubs
)
.issues(SoftwareBitmapDetector.ISSUE)
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SystemUILintDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SystemUILintDetectorTest.kt
index 2183b38..3f93f07 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SystemUILintDetectorTest.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/SystemUILintDetectorTest.kt
@@ -3,9 +3,42 @@
import com.android.tools.lint.checks.infrastructure.LintDetectorTest
import com.android.tools.lint.checks.infrastructure.TestLintTask
import java.io.File
+import org.junit.ClassRule
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.runners.model.Statement
@Suppress("UnstableApiUsage")
+@RunWith(JUnit4::class)
abstract class SystemUILintDetectorTest : LintDetectorTest() {
+
+ companion object {
+ @ClassRule
+ @JvmField
+ val libraryChecker: LibraryExists =
+ LibraryExists("framework.jar", "androidx.annotation_annotation.jar")
+ }
+
+ class LibraryExists(vararg val libraryNames: String) : TestRule {
+ override fun apply(base: Statement, description: Description): Statement {
+ return object : Statement() {
+ override fun evaluate() {
+ for (libName in libraryNames) {
+ val libFile = File(libName)
+ if (!libFile.canonicalFile.exists()) {
+ throw Exception(
+ "Could not find $libName in the test's working directory. " +
+ "File ${libFile.absolutePath} does not exist."
+ )
+ }
+ }
+ base.evaluate()
+ }
+ }
+ }
+ }
/**
* Customize the lint task to disable SDK usage completely. This ensures that running the tests
* in Android Studio has the same result as running the tests in atest
diff --git a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
index 065c314..50c3d7e 100644
--- a/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/systemui/compose/animation/ExpandableController.kt
@@ -40,17 +40,16 @@
import androidx.compose.ui.unit.LayoutDirection
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.animation.Expandable
import com.android.systemui.animation.LaunchAnimator
import kotlin.math.roundToInt
-/** A controller that can control animated launches. */
+/** A controller that can control animated launches from an [Expandable]. */
interface ExpandableController {
- /** Create an [ActivityLaunchAnimator.Controller] to animate into an Activity. */
- fun forActivity(): ActivityLaunchAnimator.Controller
-
- /** Create a [DialogLaunchAnimator.Controller] to animate into a Dialog. */
- fun forDialog(): DialogLaunchAnimator.Controller
+ /** The [Expandable] controlled by this controller. */
+ val expandable: Expandable
}
/**
@@ -120,13 +119,26 @@
private val layoutDirection: LayoutDirection,
private val isComposed: State<Boolean>,
) : ExpandableController {
- override fun forActivity(): ActivityLaunchAnimator.Controller {
- return activityController()
- }
+ override val expandable: Expandable =
+ object : Expandable {
+ override fun activityLaunchController(
+ cujType: Int?,
+ ): ActivityLaunchAnimator.Controller? {
+ if (!isComposed.value) {
+ return null
+ }
- override fun forDialog(): DialogLaunchAnimator.Controller {
- return dialogController()
- }
+ return activityController(cujType)
+ }
+
+ override fun dialogLaunchController(cuj: DialogCuj?): DialogLaunchAnimator.Controller? {
+ if (!isComposed.value) {
+ return null
+ }
+
+ return dialogController(cuj)
+ }
+ }
/**
* Create a [LaunchAnimator.Controller] that is going to be used to drive an activity or dialog
@@ -233,7 +245,7 @@
}
/** Create an [ActivityLaunchAnimator.Controller] that can be used to animate activities. */
- private fun activityController(): ActivityLaunchAnimator.Controller {
+ private fun activityController(cujType: Int?): ActivityLaunchAnimator.Controller {
val delegate = launchController()
return object : ActivityLaunchAnimator.Controller, LaunchAnimator.Controller by delegate {
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
@@ -248,10 +260,11 @@
}
}
- private fun dialogController(): DialogLaunchAnimator.Controller {
+ private fun dialogController(cuj: DialogCuj?): DialogLaunchAnimator.Controller {
return object : DialogLaunchAnimator.Controller {
override val viewRoot: ViewRootImpl = composeViewRoot.viewRootImpl
override val sourceIdentity: Any = this@ExpandableControllerImpl
+ override val cuj: DialogCuj? = cuj
override fun startDrawingInOverlayOf(viewGroup: ViewGroup) {
val newOverlay = viewGroup.overlay as ViewGroupOverlay
@@ -294,9 +307,7 @@
isDialogShowing.value = false
}
- override fun jankConfigurationBuilder(
- cuj: Int
- ): InteractionJankMonitor.Configuration.Builder? {
+ override fun jankConfigurationBuilder(): InteractionJankMonitor.Configuration.Builder? {
// TODO(b/252723237): Add support for jank monitoring when animating from a
// Composable.
return null
diff --git a/packages/SystemUI/res/drawable-hdpi/textfield_default_filled.9.png b/packages/SystemUI/res/drawable-hdpi/textfield_default_filled.9.png
new file mode 100644
index 0000000..3dd997f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/textfield_default_filled.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/textfield_default_filled.9.png b/packages/SystemUI/res/drawable-mdpi/textfield_default_filled.9.png
new file mode 100644
index 0000000..80aba01
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/textfield_default_filled.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/textfield_default_filled.9.png b/packages/SystemUI/res/drawable-xhdpi/textfield_default_filled.9.png
new file mode 100644
index 0000000..b3f89ed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/textfield_default_filled.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/textfield_default_filled.9.png b/packages/SystemUI/res/drawable-xxhdpi/textfield_default_filled.9.png
new file mode 100644
index 0000000..efa2cb9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/textfield_default_filled.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/edit_text_filled.xml b/packages/SystemUI/res/drawable/edit_text_filled.xml
new file mode 100644
index 0000000..cca34d4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/edit_text_filled.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetLeft="4dp"
+ android:insetRight="4dp"
+ android:insetTop="10dp"
+ android:insetBottom="10dp">
+ <selector>
+ <item android:state_enabled="false">
+ <nine-patch android:src="@drawable/textfield_default_filled"
+ android:tint="?android:attr/colorControlNormal" />
+ </item>
+ <item android:state_pressed="false" android:state_focused="false">
+ <nine-patch android:src="@drawable/textfield_default_filled"
+ android:tint="?android:attr/colorControlNormal" />
+ </item>
+ <item>
+ <nine-patch android:src="@drawable/textfield_default_filled"
+ android:tint="?android:attr/colorControlActivated" />
+ </item>
+ </selector>
+</inset>
diff --git a/packages/SystemUI/res/layout-land/auth_credential_password_view.xml b/packages/SystemUI/res/layout-land/auth_credential_password_view.xml
index da76c8d..3bcc37a 100644
--- a/packages/SystemUI/res/layout-land/auth_credential_password_view.xml
+++ b/packages/SystemUI/res/layout-land/auth_credential_password_view.xml
@@ -16,46 +16,74 @@
<com.android.systemui.biometrics.AuthCredentialPasswordView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
- android:gravity="center_horizontal"
- android:elevation="@dimen/biometric_dialog_elevation">
+ android:orientation="horizontal"
+ android:elevation="@dimen/biometric_dialog_elevation"
+ android:theme="?app:attr/lockPinPasswordStyle">
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Title"/>
+ <RelativeLayout
+ android:id="@+id/auth_credential_header"
+ style="?headerStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent">
- <TextView
- android:id="@+id/subtitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Subtitle"/>
+ <ImageView
+ android:id="@+id/icon"
+ style="?headerIconStyle"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:contentDescription="@null"/>
- <TextView
- android:id="@+id/description"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Description"/>
+ <TextView
+ android:id="@+id/title"
+ style="?titleTextAppearance"
+ android:layout_below="@id/icon"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
- <ImeAwareEditText
- android:id="@+id/lockPassword"
- android:layout_width="208dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:minHeight="48dp"
- android:gravity="center"
- android:inputType="textPassword"
- android:maxLength="500"
- android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
- style="@style/TextAppearance.AuthCredential.PasswordEntry"/>
+ <TextView
+ android:id="@+id/subtitle"
+ style="?subTitleTextAppearance"
+ android:layout_below="@id/title"
+ android:layout_alignParentLeft="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
- <TextView
- android:id="@+id/error"
- android:layout_width="match_parent"
+ <TextView
+ android:id="@+id/description"
+ style="?descriptionTextAppearance"
+ android:layout_below="@id/subtitle"
+ android:layout_alignParentLeft="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </RelativeLayout>
+
+ <LinearLayout
+ android:id="@+id/auth_credential_input"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Error"/>
+ android:orientation="vertical">
+
+ <ImeAwareEditText
+ android:id="@+id/lockPassword"
+ style="?passwordTextAppearance"
+ android:layout_width="208dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
+ android:inputType="textPassword"
+ android:minHeight="48dp" />
+
+ <TextView
+ android:id="@+id/error"
+ style="?errorTextAppearance"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
</com.android.systemui.biometrics.AuthCredentialPasswordView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml b/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
index 19a85fe..a3dd334 100644
--- a/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
+++ b/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
@@ -16,91 +16,71 @@
<com.android.systemui.biometrics.AuthCredentialPatternView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
- android:elevation="@dimen/biometric_dialog_elevation">
+ android:elevation="@dimen/biometric_dialog_elevation"
+ android:theme="?app:attr/lockPatternStyle">
- <LinearLayout
+ <RelativeLayout
+ android:id="@+id/auth_credential_header"
+ style="?headerStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center"
- android:orientation="vertical">
-
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1"/>
+ android:layout_weight="1">
<ImageView
android:id="@+id/icon"
+ style="?headerIconStyle"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:contentDescription="@null"/>
+
+ <TextView
+ android:id="@+id/title"
+ style="?titleTextAppearance"
+ android:layout_below="@id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Title"/>
-
- <TextView
android:id="@+id/subtitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Subtitle"/>
+ style="?subTitleTextAppearance"
+ android:layout_below="@id/title"
+ android:layout_alignParentLeft="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
<TextView
android:id="@+id/description"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Description"/>
+ style="?descriptionTextAppearance"
+ android:layout_below="@id/subtitle"
+ android:layout_alignParentLeft="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1"/>
+ </RelativeLayout>
+
+ <FrameLayout
+ android:layout_weight="1"
+ style="?containerStyle"
+ android:layout_width="0dp"
+ android:layout_height="match_parent">
+
+ <com.android.internal.widget.LockPatternView
+ android:id="@+id/lockPattern"
+ android:layout_gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
<TextView
android:id="@+id/error"
+ style="?errorTextAppearance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/TextAppearance.AuthCredential.Error"/>
+ android:layout_gravity="center_horizontal|bottom"/>
- <Space
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_weight="1"/>
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:orientation="vertical"
- android:gravity="center"
- android:paddingLeft="0dp"
- android:paddingRight="0dp"
- android:paddingTop="0dp"
- android:paddingBottom="16dp"
- android:clipToPadding="false">
-
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_weight="1"
- style="@style/LockPatternContainerStyle">
-
- <com.android.internal.widget.LockPatternView
- android:id="@+id/lockPattern"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- style="@style/LockPatternStyleBiometricPrompt"/>
-
- </FrameLayout>
-
- </LinearLayout>
+ </FrameLayout>
</com.android.systemui.biometrics.AuthCredentialPatternView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_credential_password_view.xml b/packages/SystemUI/res/layout/auth_credential_password_view.xml
index 0ff1db2..774b335f 100644
--- a/packages/SystemUI/res/layout/auth_credential_password_view.xml
+++ b/packages/SystemUI/res/layout/auth_credential_password_view.xml
@@ -16,74 +16,71 @@
<com.android.systemui.biometrics.AuthCredentialPasswordView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="@dimen/biometric_dialog_elevation"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:theme="?app:attr/lockPinPasswordStyle">
<RelativeLayout
+ android:id="@+id/auth_credential_header"
+ style="?headerStyle"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:id="@+id/icon"
+ style="?headerIconStyle"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:contentDescription="@null"/>
+
+ <TextView
+ android:id="@+id/title"
+ style="?titleTextAppearance"
+ android:layout_below="@id/icon"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ style="?subTitleTextAppearance"
+ android:layout_below="@id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <TextView
+ android:id="@+id/description"
+ style="?descriptionTextAppearance"
+ android:layout_below="@id/subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </RelativeLayout>
+
+ <LinearLayout
+ android:id="@+id/auth_credential_input"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:orientation="vertical">
- <LinearLayout
- android:id="@+id/auth_credential_header"
- style="@style/AuthCredentialHeaderStyle"
- android:layout_width="match_parent"
+ <ImeAwareEditText
+ android:id="@+id/lockPassword"
+ style="?passwordTextAppearance"
+ android:layout_width="208dp"
android:layout_height="wrap_content"
- android:layout_alignParentTop="true">
+ android:layout_gravity="center_horizontal"
+ android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
+ android:inputType="textPassword"
+ android:minHeight="48dp" />
- <ImageView
- android:id="@+id/icon"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:contentDescription="@null" />
-
- <TextView
- android:id="@+id/title"
- style="@style/TextAppearance.AuthNonBioCredential.Title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <TextView
- android:id="@+id/subtitle"
- style="@style/TextAppearance.AuthNonBioCredential.Subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <TextView
- android:id="@+id/description"
- style="@style/TextAppearance.AuthNonBioCredential.Description"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
- <LinearLayout
+ <TextView
+ android:id="@+id/error"
+ style="?errorTextAppearance"
+ android:layout_gravity="center_horizontal"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:orientation="vertical"
- android:layout_alignParentBottom="true">
+ android:layout_height="wrap_content" />
- <ImeAwareEditText
- android:id="@+id/lockPassword"
- style="@style/TextAppearance.AuthCredential.PasswordEntry"
- android:layout_width="208dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:imeOptions="actionNext|flagNoFullscreen|flagForceAscii"
- android:inputType="textPassword"
- android:minHeight="48dp" />
-
- <TextView
- android:id="@+id/error"
- style="@style/TextAppearance.AuthNonBioCredential.Error"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
- </RelativeLayout>
+ </LinearLayout>
</com.android.systemui.biometrics.AuthCredentialPasswordView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_credential_pattern_view.xml b/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
index dada981..4af9970 100644
--- a/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
+++ b/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
@@ -16,87 +16,66 @@
<com.android.systemui.biometrics.AuthCredentialPatternView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:gravity="center_horizontal"
- android:elevation="@dimen/biometric_dialog_elevation">
+ android:elevation="@dimen/biometric_dialog_elevation"
+ android:theme="?app:attr/lockPatternStyle">
<RelativeLayout
+ android:id="@+id/auth_credential_header"
+ style="?headerStyle"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="wrap_content">
- <LinearLayout
- android:id="@+id/auth_credential_header"
- style="@style/AuthCredentialHeaderStyle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ <ImageView
+ android:id="@+id/icon"
+ style="?headerIconStyle"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:contentDescription="@null"/>
- <ImageView
- android:id="@+id/icon"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:contentDescription="@null" />
+ <TextView
+ android:id="@+id/title"
+ style="?titleTextAppearance"
+ android:layout_below="@id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
- <TextView
- android:id="@+id/title"
- style="@style/TextAppearance.AuthNonBioCredential.Title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ <TextView
+ android:id="@+id/subtitle"
+ style="?subTitleTextAppearance"
+ android:layout_below="@id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
- <TextView
- android:id="@+id/subtitle"
- style="@style/TextAppearance.AuthNonBioCredential.Subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <TextView
- android:id="@+id/description"
- style="@style/TextAppearance.AuthNonBioCredential.Description"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/auth_credential_header"
- android:gravity="center"
- android:orientation="vertical"
- android:paddingBottom="16dp"
- android:paddingTop="60dp">
-
- <FrameLayout
- style="@style/LockPatternContainerStyle"
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_weight="1">
-
- <com.android.internal.widget.LockPatternView
- android:id="@+id/lockPattern"
- style="@style/LockPatternStyle"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center" />
-
- </FrameLayout>
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true">
-
- <TextView
- android:id="@+id/error"
- style="@style/TextAppearance.AuthNonBioCredential.Error"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
+ <TextView
+ android:id="@+id/description"
+ style="?descriptionTextAppearance"
+ android:layout_below="@id/subtitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
</RelativeLayout>
+ <FrameLayout
+ android:id="@+id/auth_credential_container"
+ style="?containerStyle"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.android.internal.widget.LockPatternView
+ android:id="@+id/lockPattern"
+ android:layout_gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+ <TextView
+ android:id="@+id/error"
+ style="?errorTextAppearance"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|bottom"/>
+ </FrameLayout>
+
</com.android.systemui.biometrics.AuthCredentialPatternView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index 8919198..aefd998 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -18,4 +18,42 @@
<style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer">
<item name="android:layout_width">360dp</item>
</style>
+
+ <style name="AuthCredentialHeaderStyle">
+ <item name="android:paddingStart">48dp</item>
+ <item name="android:paddingEnd">24dp</item>
+ <item name="android:paddingTop">48dp</item>
+ <item name="android:paddingBottom">10dp</item>
+ <item name="android:gravity">top|left</item>
+ </style>
+
+ <style name="AuthCredentialPatternContainerStyle">
+ <item name="android:gravity">center</item>
+ <item name="android:maxHeight">320dp</item>
+ <item name="android:maxWidth">320dp</item>
+ <item name="android:minHeight">200dp</item>
+ <item name="android:minWidth">200dp</item>
+ <item name="android:paddingHorizontal">60dp</item>
+ <item name="android:paddingVertical">20dp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Title">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">6dp</item>
+ <item name="android:textSize">36dp</item>
+ <item name="android:focusable">true</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Subtitle">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">6dp</item>
+ <item name="android:textSize">18sp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Description">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">6dp</item>
+ <item name="android:textSize">18sp</item>
+ </style>
+
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/styles.xml b/packages/SystemUI/res/values-sw600dp-land/styles.xml
new file mode 100644
index 0000000..8148d3d
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp-land/styles.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <style name="AuthCredentialPatternContainerStyle">
+ <item name="android:gravity">center</item>
+ <item name="android:maxHeight">420dp</item>
+ <item name="android:maxWidth">420dp</item>
+ <item name="android:minHeight">200dp</item>
+ <item name="android:minWidth">200dp</item>
+ <item name="android:paddingHorizontal">120dp</item>
+ <item name="android:paddingVertical">40dp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Title">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:textSize">36sp</item>
+ <item name="android:focusable">true</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Subtitle">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:textSize">18sp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Description">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:textSize">18sp</item>
+ </style>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-port/styles.xml b/packages/SystemUI/res/values-sw600dp-port/styles.xml
new file mode 100644
index 0000000..771de08
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp-port/styles.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <style name="AuthCredentialHeaderStyle">
+ <item name="android:paddingStart">120dp</item>
+ <item name="android:paddingEnd">120dp</item>
+ <item name="android:paddingTop">80dp</item>
+ <item name="android:paddingBottom">10dp</item>
+ <item name="android:layout_gravity">top</item>
+ </style>
+
+ <style name="AuthCredentialPatternContainerStyle">
+ <item name="android:gravity">center</item>
+ <item name="android:maxHeight">420dp</item>
+ <item name="android:maxWidth">420dp</item>
+ <item name="android:minHeight">200dp</item>
+ <item name="android:minWidth">200dp</item>
+ <item name="android:paddingHorizontal">180dp</item>
+ <item name="android:paddingVertical">80dp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Title">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">24dp</item>
+ <item name="android:textSize">36sp</item>
+ <item name="android:focusable">true</item>
+ </style>
+
+</resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/styles.xml b/packages/SystemUI/res/values-sw720dp-land/styles.xml
new file mode 100644
index 0000000..f9ed67d
--- /dev/null
+++ b/packages/SystemUI/res/values-sw720dp-land/styles.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <style name="AuthCredentialPatternContainerStyle">
+ <item name="android:gravity">center</item>
+ <item name="android:maxHeight">420dp</item>
+ <item name="android:maxWidth">420dp</item>
+ <item name="android:minHeight">200dp</item>
+ <item name="android:minWidth">200dp</item>
+ <item name="android:paddingHorizontal">120dp</item>
+ <item name="android:paddingVertical">40dp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Title">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:textSize">36sp</item>
+ <item name="android:focusable">true</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Subtitle">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:textSize">18sp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Description">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:textSize">18sp</item>
+ </style>
+
+</resources>
diff --git a/packages/SystemUI/res/values-sw720dp-port/styles.xml b/packages/SystemUI/res/values-sw720dp-port/styles.xml
new file mode 100644
index 0000000..78d299c
--- /dev/null
+++ b/packages/SystemUI/res/values-sw720dp-port/styles.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <style name="AuthCredentialHeaderStyle">
+ <item name="android:paddingStart">120dp</item>
+ <item name="android:paddingEnd">120dp</item>
+ <item name="android:paddingTop">80dp</item>
+ <item name="android:paddingBottom">10dp</item>
+ <item name="android:layout_gravity">top</item>
+ </style>
+
+ <style name="AuthCredentialPatternContainerStyle">
+ <item name="android:gravity">center</item>
+ <item name="android:maxHeight">420dp</item>
+ <item name="android:maxWidth">420dp</item>
+ <item name="android:minHeight">200dp</item>
+ <item name="android:minWidth">200dp</item>
+ <item name="android:paddingHorizontal">240dp</item>
+ <item name="android:paddingVertical">120dp</item>
+ </style>
+
+ <style name="TextAppearance.AuthNonBioCredential.Title">
+ <item name="android:fontFamily">google-sans</item>
+ <item name="android:layout_marginTop">24dp</item>
+ <item name="android:textSize">36sp</item>
+ <item name="android:focusable">true</item>
+ </style>
+
+</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 9a71995..df0659d 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -191,5 +191,18 @@
<declare-styleable name="DelayableMarqueeTextView">
<attr name="marqueeDelay" format="integer" />
</declare-styleable>
+
+ <declare-styleable name="AuthCredentialView">
+ <attr name="lockPatternStyle" format="reference" />
+ <attr name="lockPinPasswordStyle" format="reference" />
+ <attr name="containerStyle" format="reference" />
+ <attr name="headerStyle" format="reference" />
+ <attr name="headerIconStyle" format="reference" />
+ <attr name="titleTextAppearance" format="reference" />
+ <attr name="subTitleTextAppearance" format="reference" />
+ <attr name="descriptionTextAppearance" format="reference" />
+ <attr name="passwordTextAppearance" format="reference" />
+ <attr name="errorTextAppearance" format="reference"/>
+ </declare-styleable>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index cf100cb..93926ef9 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -950,6 +950,9 @@
<dimen name="biometric_dialog_width">240dp</dimen>
<dimen name="biometric_dialog_height">240dp</dimen>
+ <!-- Biometric Auth Credential values -->
+ <dimen name="biometric_auth_icon_size">48dp</dimen>
+
<!-- Starting text size in sp of batteryLevel for wireless charging animation -->
<item name="wireless_charging_anim_battery_level_text_size_start" format="float" type="dimen">
0
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b5011df..e76887b 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -197,8 +197,9 @@
<style name="TextAppearance.AuthNonBioCredential.Title">
<item name="android:fontFamily">google-sans</item>
- <item name="android:layout_marginTop">20dp</item>
- <item name="android:textSize">36sp</item>
+ <item name="android:layout_marginTop">24dp</item>
+ <item name="android:textSize">36dp</item>
+ <item name="android:focusable">true</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Subtitle">
@@ -210,12 +211,10 @@
<style name="TextAppearance.AuthNonBioCredential.Description">
<item name="android:fontFamily">google-sans</item>
<item name="android:layout_marginTop">20dp</item>
- <item name="android:textSize">16sp</item>
+ <item name="android:textSize">18sp</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Error">
- <item name="android:paddingTop">6dp</item>
- <item name="android:paddingBottom">18dp</item>
<item name="android:paddingHorizontal">24dp</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">?android:attr/colorError</item>
@@ -224,20 +223,43 @@
<style name="TextAppearance.AuthCredential.PasswordEntry" parent="@android:style/TextAppearance.DeviceDefault">
<item name="android:gravity">center</item>
+ <item name="android:paddingTop">28dp</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">?android:attr/colorForeground</item>
<item name="android:textSize">24sp</item>
+ <item name="android:background">@drawable/edit_text_filled</item>
</style>
<style name="AuthCredentialHeaderStyle">
<item name="android:paddingStart">48dp</item>
- <item name="android:paddingEnd">24dp</item>
- <item name="android:paddingTop">28dp</item>
- <item name="android:paddingBottom">20dp</item>
- <item name="android:orientation">vertical</item>
+ <item name="android:paddingEnd">48dp</item>
+ <item name="android:paddingTop">48dp</item>
+ <item name="android:paddingBottom">10dp</item>
<item name="android:layout_gravity">top</item>
</style>
+ <style name="AuthCredentialIconStyle">
+ <item name="android:layout_width">@dimen/biometric_auth_icon_size</item>
+ <item name="android:layout_height">@dimen/biometric_auth_icon_size</item>
+ </style>
+
+ <style name="AuthCredentialPatternContainerStyle">
+ <item name="android:gravity">center</item>
+ <item name="android:maxHeight">420dp</item>
+ <item name="android:maxWidth">420dp</item>
+ <item name="android:minHeight">200dp</item>
+ <item name="android:minWidth">200dp</item>
+ <item name="android:padding">20dp</item>
+ </style>
+
+ <style name="AuthCredentialPinPasswordContainerStyle">
+ <item name="android:gravity">center</item>
+ <item name="android:maxHeight">48dp</item>
+ <item name="android:maxWidth">600dp</item>
+ <item name="android:minHeight">48dp</item>
+ <item name="android:minWidth">200dp</item>
+ </style>
+
<style name="DeviceManagementDialogTitle">
<item name="android:gravity">center</item>
<item name="android:textAppearance">@style/TextAppearance.DeviceManagementDialog.Title</item>
@@ -275,7 +297,9 @@
<item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
<item name="wallpaperTextColorAccent">@color/material_dynamic_primary90</item>
<item name="android:colorError">@*android:color/error_color_material_dark</item>
- <item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
+ <item name="*android:lockPatternStyle">@style/LockPatternViewStyle</item>
+ <item name="lockPatternStyle">@style/LockPatternContainerStyle</item>
+ <item name="lockPinPasswordStyle">@style/LockPinPasswordContainerStyle</item>
<item name="passwordStyle">@style/PasswordTheme</item>
<item name="numPadKeyStyle">@style/NumPadKey</item>
<item name="backgroundProtectedStyle">@style/BackgroundProtectedStyle</item>
@@ -301,27 +325,33 @@
<item name="android:textColor">?attr/wallpaperTextColor</item>
</style>
- <style name="LockPatternContainerStyle">
- <item name="android:maxHeight">400dp</item>
- <item name="android:maxWidth">420dp</item>
- <item name="android:minHeight">0dp</item>
- <item name="android:minWidth">0dp</item>
- <item name="android:paddingHorizontal">60dp</item>
- <item name="android:paddingBottom">40dp</item>
+ <style name="AuthCredentialStyle">
+ <item name="*android:regularColor">?android:attr/colorForeground</item>
+ <item name="*android:successColor">?android:attr/colorForeground</item>
+ <item name="*android:errorColor">?android:attr/colorError</item>
+ <item name="*android:dotColor">?android:attr/textColorSecondary</item>
+ <item name="headerStyle">@style/AuthCredentialHeaderStyle</item>
+ <item name="headerIconStyle">@style/AuthCredentialIconStyle</item>
+ <item name="titleTextAppearance">@style/TextAppearance.AuthNonBioCredential.Title</item>
+ <item name="subTitleTextAppearance">@style/TextAppearance.AuthNonBioCredential.Subtitle</item>
+ <item name="descriptionTextAppearance">@style/TextAppearance.AuthNonBioCredential.Description</item>
+ <item name="passwordTextAppearance">@style/TextAppearance.AuthCredential.PasswordEntry</item>
+ <item name="errorTextAppearance">@style/TextAppearance.AuthNonBioCredential.Error</item>
</style>
- <style name="LockPatternStyle">
+ <style name="LockPatternViewStyle" >
<item name="*android:regularColor">?android:attr/colorAccent</item>
<item name="*android:successColor">?android:attr/textColorPrimary</item>
<item name="*android:errorColor">?android:attr/colorError</item>
<item name="*android:dotColor">?android:attr/textColorSecondary</item>
</style>
- <style name="LockPatternStyleBiometricPrompt">
- <item name="*android:regularColor">?android:attr/colorForeground</item>
- <item name="*android:successColor">?android:attr/colorForeground</item>
- <item name="*android:errorColor">?android:attr/colorError</item>
- <item name="*android:dotColor">?android:attr/textColorSecondary</item>
+ <style name="LockPatternContainerStyle" parent="@style/AuthCredentialStyle">
+ <item name="containerStyle">@style/AuthCredentialPatternContainerStyle</item>
+ </style>
+
+ <style name="LockPinPasswordContainerStyle" parent="@style/AuthCredentialStyle">
+ <item name="containerStyle">@style/AuthCredentialPinPasswordContainerStyle</item>
</style>
<style name="Theme.SystemUI.QuickSettings" parent="@*android:style/Theme.DeviceDefault">
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ExternalViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ExternalViewScreenshotTestRule.kt
index 2e391c7..49cc483 100644
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ExternalViewScreenshotTestRule.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ExternalViewScreenshotTestRule.kt
@@ -19,6 +19,7 @@
import android.app.Activity
import android.graphics.Color
import android.view.View
+import android.view.Window
import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
@@ -51,13 +52,14 @@
/**
* Compare the content of the [view] with the golden image identified by [goldenIdentifier] in
- * the context of [emulationSpec].
+ * the context of [emulationSpec]. Window must be specified to capture views that render
+ * hardware buffers.
*/
- fun screenshotTest(goldenIdentifier: String, view: View) {
+ fun screenshotTest(goldenIdentifier: String, view: View, window: Window? = null) {
view.removeElevationRecursively()
ScreenshotRuleAsserter.Builder(screenshotRule)
- .setScreenshotProvider { view.toBitmap() }
+ .setScreenshotProvider { view.toBitmap(window) }
.withMatcher(matcher)
.build()
.assertGoldenImage(goldenIdentifier)
@@ -94,6 +96,6 @@
activity.currentFocus?.clearFocus()
}
- screenshotTest(goldenIdentifier, rootView)
+ screenshotTest(goldenIdentifier, rootView, activity.window)
}
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
index 72f8b7b..40c8774 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
@@ -1,13 +1,16 @@
package com.android.systemui.shared.recents.utilities;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.view.Surface;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.wm.shell.util.SplitBounds;
/**
* Utility class to position the thumbnail in the TaskView
@@ -16,10 +19,26 @@
public static final float MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT = 0.1f;
+ /**
+ * Specifies that a stage is positioned at the top half of the screen if
+ * in portrait mode or at the left half of the screen if in landscape mode.
+ * TODO(b/254378592): Remove after consolidation
+ */
+ public static final int STAGE_POSITION_TOP_OR_LEFT = 0;
+
+ /**
+ * Specifies that a stage is positioned at the bottom half of the screen if
+ * in portrait mode or at the right half of the screen if in landscape mode.
+ * TODO(b/254378592): Remove after consolidation
+ */
+ public static final int STAGE_POSITION_BOTTOM_OR_RIGHT = 1;
+
// Contains the portion of the thumbnail that is unclipped when fullscreen progress = 1.
private final RectF mClippedInsets = new RectF();
private final Matrix mMatrix = new Matrix();
private boolean mIsOrientationChanged;
+ private SplitBounds mSplitBounds;
+ private int mDesiredStagePosition;
public Matrix getMatrix() {
return mMatrix;
@@ -33,6 +52,11 @@
return mIsOrientationChanged;
}
+ public void setSplitBounds(SplitBounds splitBounds, int desiredStagePosition) {
+ mSplitBounds = splitBounds;
+ mDesiredStagePosition = desiredStagePosition;
+ }
+
/**
* Updates the matrix based on the provided parameters
*/
@@ -42,10 +66,19 @@
boolean isRotated = false;
boolean isOrientationDifferent;
+ float fullscreenTaskWidth = screenWidthPx;
+ if (mSplitBounds != null && !mSplitBounds.appsStackedVertically) {
+ // For landscape, scale the width
+ float taskPercent = mDesiredStagePosition == STAGE_POSITION_TOP_OR_LEFT
+ ? mSplitBounds.leftTaskPercent
+ : (1 - (mSplitBounds.leftTaskPercent + mSplitBounds.dividerWidthPercent));
+ // Scale landscape width to that of actual screen
+ fullscreenTaskWidth = screenWidthPx * taskPercent;
+ }
int thumbnailRotation = thumbnailData.rotation;
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
RectF thumbnailClipHint = new RectF();
- float canvasScreenRatio = canvasWidth / (float) screenWidthPx;
+ float canvasScreenRatio = canvasWidth / fullscreenTaskWidth;
float scaledTaskbarSize = taskbarSize * canvasScreenRatio;
thumbnailClipHint.bottom = isTablet ? scaledTaskbarSize : 0;
@@ -180,7 +213,7 @@
* portrait or vice versa, {@code false} otherwise
*/
private boolean isOrientationChange(int deltaRotation) {
- return deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270;
+ return deltaRotation == ROTATION_90 || deltaRotation == ROTATION_270;
}
private void setThumbnailRotation(int deltaRotate, Rect thumbnailPosition) {
@@ -189,13 +222,13 @@
mMatrix.setRotate(90 * deltaRotate);
switch (deltaRotate) { /* Counter-clockwise */
- case Surface.ROTATION_90:
+ case ROTATION_90:
translateX = thumbnailPosition.height();
break;
- case Surface.ROTATION_270:
+ case ROTATION_270:
translateY = thumbnailPosition.width();
break;
- case Surface.ROTATION_180:
+ case ROTATION_180:
translateX = thumbnailPosition.width();
translateY = thumbnailPosition.height();
break;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
index 0892612..76cd3f4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
@@ -16,12 +16,21 @@
package com.android.systemui.biometrics;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.WindowInsets.Type.ime;
+
import android.annotation.NonNull;
import android.content.Context;
+import android.graphics.Insets;
import android.os.UserHandle;
import android.text.InputType;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnApplyWindowInsetsListener;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImeAwareEditText;
@@ -31,18 +40,24 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import java.io.PrintWriter;
+
/**
* Pin and Password UI
*/
public class AuthCredentialPasswordView extends AuthCredentialView
- implements TextView.OnEditorActionListener {
+ implements TextView.OnEditorActionListener, OnApplyWindowInsetsListener, Dumpable {
private static final String TAG = "BiometricPrompt/AuthCredentialPasswordView";
private final InputMethodManager mImm;
private ImeAwareEditText mPasswordField;
+ private ViewGroup mAuthCredentialHeader;
+ private ViewGroup mAuthCredentialInput;
+ private int mBottomInset = 0;
public AuthCredentialPasswordView(Context context,
AttributeSet attrs) {
@@ -53,6 +68,9 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+
+ mAuthCredentialHeader = findViewById(R.id.auth_credential_header);
+ mAuthCredentialInput = findViewById(R.id.auth_credential_input);
mPasswordField = findViewById(R.id.lockPassword);
mPasswordField.setOnEditorActionListener(this);
// TODO: De-dupe the logic with AuthContainerView
@@ -66,6 +84,8 @@
}
return true;
});
+
+ setOnApplyWindowInsetsListener(this);
}
@Override
@@ -127,4 +147,92 @@
mPasswordField.setText("");
}
}
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ if (mAuthCredentialInput == null || mAuthCredentialHeader == null || mSubtitleView == null
+ || mDescriptionView == null || mPasswordField == null || mErrorView == null) {
+ return;
+ }
+
+ int inputLeftBound;
+ int inputTopBound;
+ int headerRightBound = right;
+ int headerTopBounds = top;
+ final int subTitleBottom = (mSubtitleView.getVisibility() == GONE) ? mTitleView.getBottom()
+ : mSubtitleView.getBottom();
+ final int descBottom = (mDescriptionView.getVisibility() == GONE) ? subTitleBottom
+ : mDescriptionView.getBottom();
+ if (getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
+ inputTopBound = (bottom - mAuthCredentialInput.getHeight()) / 2;
+ inputLeftBound = (right - left) / 2;
+ headerRightBound = inputLeftBound;
+ headerTopBounds -= Math.min(mIconView.getBottom(), mBottomInset);
+ } else {
+ inputTopBound =
+ descBottom + (bottom - descBottom - mAuthCredentialInput.getHeight()) / 2;
+ inputLeftBound = (right - left - mAuthCredentialInput.getWidth()) / 2;
+ }
+
+ if (mDescriptionView.getBottom() > mBottomInset) {
+ mAuthCredentialHeader.layout(left, headerTopBounds, headerRightBound, bottom);
+ }
+ mAuthCredentialInput.layout(inputLeftBound, inputTopBound, right, bottom);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ final int newWidth = MeasureSpec.getSize(widthMeasureSpec);
+ final int newHeight = MeasureSpec.getSize(heightMeasureSpec) - mBottomInset;
+
+ setMeasuredDimension(newWidth, newHeight);
+
+ final int halfWidthSpec = MeasureSpec.makeMeasureSpec(getWidth() / 2,
+ MeasureSpec.AT_MOST);
+ final int fullHeightSpec = MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.UNSPECIFIED);
+ if (getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
+ measureChildren(halfWidthSpec, fullHeightSpec);
+ } else {
+ measureChildren(widthMeasureSpec, fullHeightSpec);
+ }
+ }
+
+ @NonNull
+ @Override
+ public WindowInsets onApplyWindowInsets(@NonNull View v, WindowInsets insets) {
+
+ final Insets bottomInset = insets.getInsets(ime());
+ if (v instanceof AuthCredentialPasswordView && mBottomInset != bottomInset.bottom) {
+ mBottomInset = bottomInset.bottom;
+ if (mBottomInset > 0
+ && getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
+ mTitleView.setSingleLine(true);
+ mTitleView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
+ mTitleView.setMarqueeRepeatLimit(-1);
+ // select to enable marquee unless a screen reader is enabled
+ mTitleView.setSelected(!mAccessibilityManager.isEnabled()
+ || !mAccessibilityManager.isTouchExplorationEnabled());
+ } else {
+ mTitleView.setSingleLine(false);
+ mTitleView.setEllipsize(null);
+ // select to enable marquee unless a screen reader is enabled
+ mTitleView.setSelected(false);
+ }
+ requestLayout();
+ }
+ return insets;
+ }
+
+ @Override
+ public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
+ pw.println(TAG + "State:");
+ pw.println(" mBottomInset=" + mBottomInset);
+ pw.println(" mAuthCredentialHeader size=(" + mAuthCredentialHeader.getWidth() + ","
+ + mAuthCredentialHeader.getHeight());
+ pw.println(" mAuthCredentialInput size=(" + mAuthCredentialInput.getWidth() + ","
+ + mAuthCredentialInput.getHeight());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
index 11498db..f9e44a0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
@@ -93,7 +93,9 @@
@Override
protected void onErrorTimeoutFinish() {
super.onErrorTimeoutFinish();
- mLockPatternView.setEnabled(true);
+ // select to enable marquee unless a screen reader is enabled
+ mLockPatternView.setEnabled(!mAccessibilityManager.isEnabled()
+ || !mAccessibilityManager.isTouchExplorationEnabled());
}
public AuthCredentialPatternView(Context context, AttributeSet attrs) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
index 4fa835e..5958e6a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
@@ -30,7 +30,6 @@
import android.content.Context;
import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
-import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.PromptInfo;
import android.os.AsyncTask;
import android.os.CountDownTimer;
@@ -77,7 +76,7 @@
protected final Handler mHandler;
protected final LockPatternUtils mLockPatternUtils;
- private final AccessibilityManager mAccessibilityManager;
+ protected final AccessibilityManager mAccessibilityManager;
private final UserManager mUserManager;
private final DevicePolicyManager mDevicePolicyManager;
@@ -86,10 +85,10 @@
private boolean mShouldAnimatePanel;
private boolean mShouldAnimateContents;
- private TextView mTitleView;
- private TextView mSubtitleView;
- private TextView mDescriptionView;
- private ImageView mIconView;
+ protected TextView mTitleView;
+ protected TextView mSubtitleView;
+ protected TextView mDescriptionView;
+ protected ImageView mIconView;
protected TextView mErrorView;
protected @Utils.CredentialType int mCredentialType;
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 027187c..00a9ddf 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -363,6 +363,10 @@
// 1700 - clipboard
public static final UnreleasedFlag CLIPBOARD_OVERLAY_REFACTOR = new UnreleasedFlag(1700);
+ // 1800 - shade container
+ public static final UnreleasedFlag LEAVE_SHADE_OPEN_FOR_BUGREPORT =
+ new UnreleasedFlag(1800, true);
+
// Pay no attention to the reflection behind the curtain.
// ========================== Curtain ==========================
// | |
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index da5819a..3ef5499 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -116,6 +116,7 @@
import com.android.systemui.MultiListLayout.MultiListAdapter;
import com.android.systemui.animation.DialogCuj;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.animation.Expandable;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -448,10 +449,11 @@
*
* @param keyguardShowing True if keyguard is showing
* @param isDeviceProvisioned True if device is provisioned
- * @param view The view from which we should animate the dialog when showing it
+ * @param expandable The expandable from which we should animate the dialog when
+ * showing it
*/
public void showOrHideDialog(boolean keyguardShowing, boolean isDeviceProvisioned,
- @Nullable View view) {
+ @Nullable Expandable expandable) {
mKeyguardShowing = keyguardShowing;
mDeviceProvisioned = isDeviceProvisioned;
if (mDialog != null && mDialog.isShowing()) {
@@ -463,7 +465,7 @@
mDialog.dismiss();
mDialog = null;
} else {
- handleShow(view);
+ handleShow(expandable);
}
}
@@ -495,7 +497,7 @@
}
}
- protected void handleShow(@Nullable View view) {
+ protected void handleShow(@Nullable Expandable expandable) {
awakenIfNecessary();
mDialog = createDialog();
prepareDialog();
@@ -507,10 +509,12 @@
// Don't acquire soft keyboard focus, to avoid destroying state when capturing bugreports
mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
- if (view != null) {
- mDialogLaunchAnimator.showFromView(mDialog, view,
- new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
- INTERACTION_JANK_TAG));
+ DialogLaunchAnimator.Controller controller =
+ expandable != null ? expandable.dialogLaunchController(
+ new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+ INTERACTION_JANK_TAG)) : null;
+ if (controller != null) {
+ mDialogLaunchAnimator.show(mDialog, controller);
} else {
mDialog.show();
}
@@ -1016,8 +1020,9 @@
Log.w(TAG, "Bugreport handler could not be launched");
mIActivityManager.requestInteractiveBugReport();
}
- // Close shade so user sees the activity
- mCentralSurfacesOptional.ifPresent(CentralSurfaces::collapseShade);
+ // Maybe close shade (depends on a flag) so user sees the activity
+ mCentralSurfacesOptional.ifPresent(
+ CentralSurfaces::collapseShadeForBugreport);
} catch (RemoteException e) {
}
}
@@ -1036,8 +1041,8 @@
mMetricsLogger.action(MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_FULL);
mUiEventLogger.log(GlobalActionsEvent.GA_BUGREPORT_LONG_PRESS);
mIActivityManager.requestFullBugReport();
- // Close shade so user sees the activity
- mCentralSurfacesOptional.ifPresent(CentralSurfaces::collapseShade);
+ // Maybe close shade (depends on a flag) so user sees the activity
+ mCentralSurfacesOptional.ifPresent(CentralSurfaces::collapseShadeForBugreport);
} catch (RemoteException e) {
}
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
index 1ac2a07..be357ee 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -182,8 +182,7 @@
override fun shouldGetOnlyDefaultActivities() = false
- // TODO(b/240924732) flip the flag when the recents selector is ready
- override fun shouldShowContentPreview() = false
+ override fun shouldShowContentPreview() = true
override fun createContentPreviewView(parent: ViewGroup): ViewGroup =
recentsViewController.createView(parent)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 482a139..bb2b441 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -52,6 +52,7 @@
import com.android.systemui.R
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.animation.Expandable
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
@@ -98,10 +99,10 @@
fun init()
/**
- * Show the foreground services dialog. The dialog will be expanded from [viewLaunchedFrom] if
+ * Show the foreground services dialog. The dialog will be expanded from [expandable] if
* it's not `null`.
*/
- fun showDialog(viewLaunchedFrom: View?)
+ fun showDialog(expandable: Expandable?)
/** Add a [OnNumberOfPackagesChangedListener]. */
fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener)
@@ -367,7 +368,7 @@
override fun shouldUpdateFooterVisibility() = dialog == null
- override fun showDialog(viewLaunchedFrom: View?) {
+ override fun showDialog(expandable: Expandable?) {
synchronized(lock) {
if (dialog == null) {
@@ -403,16 +404,18 @@
}
mainExecutor.execute {
- viewLaunchedFrom
- ?.let {
- dialogLaunchAnimator.showFromView(
- dialog, it,
- cuj = DialogCuj(
- InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
- INTERACTION_JANK_TAG
- )
+ val controller =
+ expandable?.dialogLaunchController(
+ DialogCuj(
+ InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+ INTERACTION_JANK_TAG,
)
- } ?: dialog.show()
+ )
+ if (controller != null) {
+ dialogLaunchAnimator.show(dialog, controller)
+ } else {
+ dialog.show()
+ }
}
backgroundExecutor.execute {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
index 9d64781..a9943e8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
@@ -32,6 +32,7 @@
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.Expandable
import com.android.systemui.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
@@ -156,7 +157,7 @@
startSettingsActivity()
} else if (v === powerMenuLite) {
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
- globalActionsDialog?.showOrHideDialog(false, true, v)
+ globalActionsDialog?.showOrHideDialog(false, true, Expandable.fromView(powerMenuLite))
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
index 7511278e..b1b9dd7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
@@ -29,6 +29,7 @@
import androidx.annotation.Nullable;
import com.android.systemui.R;
+import com.android.systemui.animation.Expandable;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.dagger.QSScope;
@@ -130,7 +131,7 @@
@Override
public void onClick(View view) {
- mFgsManagerController.showDialog(mRootView);
+ mFgsManagerController.showDialog(Expandable.fromView(view));
}
public void refreshState() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 67bf300..6c1e956 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -39,6 +39,7 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
+import com.android.systemui.animation.Expandable;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.common.shared.model.Icon;
import com.android.systemui.dagger.qualifiers.Background;
@@ -169,7 +170,7 @@
// TODO(b/242040009): Remove this.
public void showDeviceMonitoringDialog() {
- mQSSecurityFooterUtils.showDeviceMonitoringDialog(mContext, mView);
+ mQSSecurityFooterUtils.showDeviceMonitoringDialog(mContext, Expandable.fromView(mView));
}
public void refreshState() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
index ae6ed20..67bc769 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
@@ -75,6 +75,7 @@
import com.android.systemui.R;
import com.android.systemui.animation.DialogCuj;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.animation.Expandable;
import com.android.systemui.common.shared.model.ContentDescription;
import com.android.systemui.common.shared.model.Icon;
import com.android.systemui.dagger.SysUISingleton;
@@ -190,8 +191,9 @@
}
/** Show the device monitoring dialog. */
- public void showDeviceMonitoringDialog(Context quickSettingsContext, @Nullable View view) {
- createDialog(quickSettingsContext, view);
+ public void showDeviceMonitoringDialog(Context quickSettingsContext,
+ @Nullable Expandable expandable) {
+ createDialog(quickSettingsContext, expandable);
}
/**
@@ -440,7 +442,7 @@
}
}
- private void createDialog(Context quickSettingsContext, @Nullable View view) {
+ private void createDialog(Context quickSettingsContext, @Nullable Expandable expandable) {
mShouldUseSettingsButton.set(false);
mBgHandler.post(() -> {
String settingsButtonText = getSettingsButton();
@@ -453,9 +455,12 @@
? settingsButtonText : getNegativeButton(), this);
mDialog.setView(dialogView);
- if (view != null && view.isAggregatedVisible()) {
- mDialogLaunchAnimator.showFromView(mDialog, view, new DialogCuj(
- InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG));
+ DialogLaunchAnimator.Controller controller =
+ expandable != null ? expandable.dialogLaunchController(new DialogCuj(
+ InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG))
+ : null;
+ if (controller != null) {
+ mDialogLaunchAnimator.show(mDialog, controller);
} else {
mDialog.show();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt
index cf9b41c..9ba3501 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractor.kt
@@ -23,13 +23,11 @@
import android.content.IntentFilter
import android.os.UserHandle
import android.provider.Settings
-import android.view.View
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.nano.MetricsProto
import com.android.internal.util.FrameworkStatsLog
-import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
@@ -74,37 +72,27 @@
val deviceMonitoringDialogRequests: Flow<Unit>
/**
- * Show the device monitoring dialog, expanded from [view].
- *
- * Important: [view] must be associated to the same [Context] as the [Quick Settings fragment]
- * [com.android.systemui.qs.QSFragment].
- */
- // TODO(b/230830644): Replace view by Expandable interface.
- fun showDeviceMonitoringDialog(view: View)
-
- /**
- * Show the device monitoring dialog.
+ * Show the device monitoring dialog, expanded from [expandable] if it's not null.
*
* Important: [quickSettingsContext] *must* be the [Context] associated to the [Quick Settings
* fragment][com.android.systemui.qs.QSFragment].
*/
- // TODO(b/230830644): Replace view by Expandable interface.
- fun showDeviceMonitoringDialog(quickSettingsContext: Context)
+ fun showDeviceMonitoringDialog(quickSettingsContext: Context, expandable: Expandable?)
/** Show the foreground services dialog. */
- // TODO(b/230830644): Replace view by Expandable interface.
- fun showForegroundServicesDialog(view: View)
+ fun showForegroundServicesDialog(expandable: Expandable)
/** Show the power menu dialog. */
- // TODO(b/230830644): Replace view by Expandable interface.
- fun showPowerMenuDialog(globalActionsDialogLite: GlobalActionsDialogLite, view: View)
+ fun showPowerMenuDialog(
+ globalActionsDialogLite: GlobalActionsDialogLite,
+ expandable: Expandable,
+ )
/** Show the settings. */
fun showSettings(expandable: Expandable)
/** Show the user switcher. */
- // TODO(b/230830644): Replace view by Expandable interface.
- fun showUserSwitcher(view: View)
+ fun showUserSwitcher(context: Context, expandable: Expandable)
}
@SysUISingleton
@@ -147,28 +135,32 @@
null,
)
- override fun showDeviceMonitoringDialog(view: View) {
- qsSecurityFooterUtils.showDeviceMonitoringDialog(view.context, view)
- DevicePolicyEventLogger.createEvent(
- FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED
- )
- .write()
+ override fun showDeviceMonitoringDialog(
+ quickSettingsContext: Context,
+ expandable: Expandable?,
+ ) {
+ qsSecurityFooterUtils.showDeviceMonitoringDialog(quickSettingsContext, expandable)
+ if (expandable != null) {
+ DevicePolicyEventLogger.createEvent(
+ FrameworkStatsLog.DEVICE_POLICY_EVENT__EVENT_ID__DO_USER_INFO_CLICKED
+ )
+ .write()
+ }
}
- override fun showDeviceMonitoringDialog(quickSettingsContext: Context) {
- qsSecurityFooterUtils.showDeviceMonitoringDialog(quickSettingsContext, /* view= */ null)
+ override fun showForegroundServicesDialog(expandable: Expandable) {
+ fgsManagerController.showDialog(expandable)
}
- override fun showForegroundServicesDialog(view: View) {
- fgsManagerController.showDialog(view)
- }
-
- override fun showPowerMenuDialog(globalActionsDialogLite: GlobalActionsDialogLite, view: View) {
+ override fun showPowerMenuDialog(
+ globalActionsDialogLite: GlobalActionsDialogLite,
+ expandable: Expandable,
+ ) {
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
globalActionsDialogLite.showOrHideDialog(
/* keyguardShowing= */ false,
/* isDeviceProvisioned= */ true,
- view,
+ expandable,
)
}
@@ -189,21 +181,21 @@
)
}
- override fun showUserSwitcher(view: View) {
+ override fun showUserSwitcher(context: Context, expandable: Expandable) {
if (!featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)) {
- userSwitchDialogController.showDialog(view)
+ userSwitchDialogController.showDialog(context, expandable)
return
}
val intent =
- Intent(view.context, UserSwitcherActivity::class.java).apply {
+ Intent(context, UserSwitcherActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
}
activityStarter.startActivity(
intent,
true /* dismissShade */,
- ActivityLaunchAnimator.Controller.fromView(view, null),
+ expandable.activityLaunchController(),
true /* showOverlockscreenwhenlocked */,
UserHandle.SYSTEM,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
index dd1ffcc..3e39c8e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/binder/FooterActionsViewBinder.kt
@@ -31,6 +31,7 @@
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.R
+import com.android.systemui.animation.Expandable
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.people.ui.view.PeopleViewBinder.bind
@@ -125,7 +126,7 @@
launch {
viewModel.security.collect { security ->
if (previousSecurity != security) {
- bindSecurity(securityHolder, security)
+ bindSecurity(view.context, securityHolder, security)
previousSecurity = security
}
}
@@ -159,6 +160,7 @@
}
private fun bindSecurity(
+ quickSettingsContext: Context,
securityHolder: TextButtonViewHolder,
security: FooterActionsSecurityButtonViewModel?,
) {
@@ -171,9 +173,12 @@
// Make sure that the chevron is visible and that the button is clickable if there is a
// listener.
val chevron = securityHolder.chevron
- if (security.onClick != null) {
+ val onClick = security.onClick
+ if (onClick != null) {
securityView.isClickable = true
- securityView.setOnClickListener(security.onClick)
+ securityView.setOnClickListener {
+ onClick(quickSettingsContext, Expandable.fromView(securityView))
+ }
chevron.isVisible = true
} else {
securityView.isClickable = false
@@ -205,7 +210,9 @@
foregroundServicesWithNumberView.isVisible = false
foregroundServicesWithTextView.isVisible = true
- foregroundServicesWithTextView.setOnClickListener(foregroundServices.onClick)
+ foregroundServicesWithTextView.setOnClickListener {
+ foregroundServices.onClick(Expandable.fromView(foregroundServicesWithTextView))
+ }
foregroundServicesWithTextHolder.text.text = foregroundServices.text
foregroundServicesWithTextHolder.newDot.isVisible = foregroundServices.hasNewChanges
} else {
@@ -213,7 +220,9 @@
foregroundServicesWithTextView.isVisible = false
foregroundServicesWithNumberView.visibility = View.VISIBLE
- foregroundServicesWithNumberView.setOnClickListener(foregroundServices.onClick)
+ foregroundServicesWithNumberView.setOnClickListener {
+ foregroundServices.onClick(Expandable.fromView(foregroundServicesWithTextView))
+ }
foregroundServicesWithNumberHolder.number.text = foregroundServicesCount.toString()
foregroundServicesWithNumberHolder.number.contentDescription = foregroundServices.text
foregroundServicesWithNumberHolder.newDot.isVisible = foregroundServices.hasNewChanges
@@ -229,7 +238,7 @@
}
buttonView.setBackgroundResource(model.background)
- buttonView.setOnClickListener(model.onClick)
+ buttonView.setOnClickListener { model.onClick(Expandable.fromView(buttonView)) }
val icon = model.icon
val iconView = button.icon
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
index 9b5f683..8d819da 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsButtonViewModel.kt
@@ -17,7 +17,7 @@
package com.android.systemui.qs.footer.ui.viewmodel
import android.annotation.DrawableRes
-import android.view.View
+import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
/**
@@ -29,7 +29,5 @@
val icon: Icon,
val iconTint: Int?,
@DrawableRes val background: Int,
- // TODO(b/230830644): Replace View by an Expandable interface that can expand in either dialog
- // or activity.
- val onClick: (View) -> Unit,
+ val onClick: (Expandable) -> Unit,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsForegroundServicesButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsForegroundServicesButtonViewModel.kt
index 98b53cb..ff8130d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsForegroundServicesButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsForegroundServicesButtonViewModel.kt
@@ -16,7 +16,7 @@
package com.android.systemui.qs.footer.ui.viewmodel
-import android.view.View
+import com.android.systemui.animation.Expandable
/** A ViewModel for the foreground services button. */
data class FooterActionsForegroundServicesButtonViewModel(
@@ -24,5 +24,5 @@
val text: String,
val displayText: Boolean,
val hasNewChanges: Boolean,
- val onClick: (View) -> Unit,
+ val onClick: (Expandable) -> Unit,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsSecurityButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsSecurityButtonViewModel.kt
index 98ab129..3450505 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsSecurityButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsSecurityButtonViewModel.kt
@@ -16,12 +16,13 @@
package com.android.systemui.qs.footer.ui.viewmodel
-import android.view.View
+import android.content.Context
+import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
/** A ViewModel for the security button. */
data class FooterActionsSecurityButtonViewModel(
val icon: Icon,
val text: String,
- val onClick: ((View) -> Unit)?,
+ val onClick: ((quickSettingsContext: Context, Expandable) -> Unit)?,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index d3c06f6..dee6fad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -18,7 +18,6 @@
import android.content.Context
import android.util.Log
-import android.view.View
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
@@ -199,50 +198,51 @@
*/
suspend fun observeDeviceMonitoringDialogRequests(quickSettingsContext: Context) {
footerActionsInteractor.deviceMonitoringDialogRequests.collect {
- footerActionsInteractor.showDeviceMonitoringDialog(quickSettingsContext)
+ footerActionsInteractor.showDeviceMonitoringDialog(
+ quickSettingsContext,
+ expandable = null,
+ )
}
}
- private fun onSecurityButtonClicked(view: View) {
+ private fun onSecurityButtonClicked(quickSettingsContext: Context, expandable: Expandable) {
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return
}
- footerActionsInteractor.showDeviceMonitoringDialog(view)
+ footerActionsInteractor.showDeviceMonitoringDialog(quickSettingsContext, expandable)
}
- private fun onForegroundServiceButtonClicked(view: View) {
+ private fun onForegroundServiceButtonClicked(expandable: Expandable) {
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return
}
- footerActionsInteractor.showForegroundServicesDialog(view)
+ footerActionsInteractor.showForegroundServicesDialog(expandable)
}
- private fun onUserSwitcherClicked(view: View) {
+ private fun onUserSwitcherClicked(expandable: Expandable) {
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return
}
- footerActionsInteractor.showUserSwitcher(view)
+ footerActionsInteractor.showUserSwitcher(context, expandable)
}
- // TODO(b/230830644): Replace View by an Expandable interface that can expand in either dialog
- // or activity.
- private fun onSettingsButtonClicked(view: View) {
+ private fun onSettingsButtonClicked(expandable: Expandable) {
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return
}
- footerActionsInteractor.showSettings(Expandable.fromView(view))
+ footerActionsInteractor.showSettings(expandable)
}
- private fun onPowerButtonClicked(view: View) {
+ private fun onPowerButtonClicked(expandable: Expandable) {
if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return
}
- footerActionsInteractor.showPowerMenuDialog(globalActionsDialogLite, view)
+ footerActionsInteractor.showPowerMenuDialog(globalActionsDialogLite, expandable)
}
private fun userSwitcherButton(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
index bdcc6b0..314252b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
@@ -23,13 +23,13 @@
import android.content.Intent
import android.provider.Settings
import android.view.LayoutInflater
-import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.UiEventLogger
import com.android.systemui.R
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
@@ -77,10 +77,10 @@
* Show a [UserDialog].
*
* Populate the dialog with information from and adapter obtained from
- * [userDetailViewAdapterProvider] and show it as launched from [view].
+ * [userDetailViewAdapterProvider] and show it as launched from [expandable].
*/
- fun showDialog(view: View) {
- with(dialogFactory(view.context)) {
+ fun showDialog(context: Context, expandable: Expandable) {
+ with(dialogFactory(context)) {
setShowForAllUsers(true)
setCanceledOnTouchOutside(true)
@@ -112,13 +112,19 @@
adapter.linkToViewGroup(gridFrame.findViewById(R.id.grid))
- dialogLaunchAnimator.showFromView(
- this, view,
- cuj = DialogCuj(
- InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
- INTERACTION_JANK_TAG
+ val controller =
+ expandable.dialogLaunchController(
+ DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG)
)
- )
+ if (controller != null) {
+ dialogLaunchAnimator.show(
+ this,
+ controller,
+ )
+ } else {
+ show()
+ }
+
uiEventLogger.log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
adapter.injectDialogShower(DialogShowerImpl(this, dialogLaunchAnimator))
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index 8f3eb4f..8a31ed9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -18,6 +18,8 @@
import android.app.Notification
import android.app.Notification.GROUP_ALERT_SUMMARY
import android.util.ArrayMap
+import android.util.ArraySet
+import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.statusbar.NotificationRemoteInputManager
import com.android.systemui.statusbar.notification.collection.GroupEntry
@@ -70,6 +72,7 @@
@Main private val mExecutor: DelayableExecutor,
) : Coordinator {
private val mEntriesBindingUntil = ArrayMap<String, Long>()
+ private val mEntriesUpdateTimes = ArrayMap<String, Long>()
private var mEndLifetimeExtension: OnEndLifetimeExtensionCallback? = null
private lateinit var mNotifPipeline: NotifPipeline
private var mNow: Long = -1
@@ -264,6 +267,9 @@
}
// After this method runs, all posted entries should have been handled (or skipped).
mPostedEntries.clear()
+
+ // Also take this opportunity to clean up any stale entry update times
+ cleanUpEntryUpdateTimes()
}
/**
@@ -378,6 +384,9 @@
isAlerting = false,
isBinding = false,
)
+
+ // Record the last updated time for this key
+ setUpdateTime(entry, mSystemClock.currentTimeMillis())
}
/**
@@ -419,6 +428,9 @@
cancelHeadsUpBind(posted.entry)
}
}
+
+ // Update last updated time for this entry
+ setUpdateTime(entry, mSystemClock.currentTimeMillis())
}
/**
@@ -426,6 +438,7 @@
*/
override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
mPostedEntries.remove(entry.key)
+ mEntriesUpdateTimes.remove(entry.key)
cancelHeadsUpBind(entry)
val entryKey = entry.key
if (mHeadsUpManager.isAlerting(entryKey)) {
@@ -454,7 +467,12 @@
// never) in mPostedEntries to need to alert, we need to check every notification
// known to the pipeline.
for (entry in mNotifPipeline.allNotifs) {
- // The only entries we can consider alerting for here are entries that have never
+ // Only consider entries that are recent enough, since we want to apply a fairly
+ // strict threshold for when an entry should be updated via only ranking and not an
+ // app-provided notification update.
+ if (!isNewEnoughForRankingUpdate(entry)) continue
+
+ // The only entries we consider alerting for here are entries that have never
// interrupted and that now say they should heads up; if they've alerted in the
// past, we don't want to incorrectly alert a second time if there wasn't an
// explicit notification update.
@@ -486,6 +504,41 @@
(entry.sbn.notification.flags and Notification.FLAG_ONLY_ALERT_ONCE) == 0)
}
+ /**
+ * Sets the updated time for the given entry to the specified time.
+ */
+ @VisibleForTesting
+ fun setUpdateTime(entry: NotificationEntry, time: Long) {
+ mEntriesUpdateTimes[entry.key] = time
+ }
+
+ /**
+ * Checks whether the entry is new enough to be updated via ranking update.
+ * We want to avoid updating an entry too long after it was originally posted/updated when we're
+ * only reacting to a ranking change, as relevant ranking updates are expected to come in
+ * fairly soon after the posting of a notification.
+ */
+ private fun isNewEnoughForRankingUpdate(entry: NotificationEntry): Boolean {
+ // If we don't have an update time for this key, default to "too old"
+ if (!mEntriesUpdateTimes.containsKey(entry.key)) return false
+
+ val updateTime = mEntriesUpdateTimes[entry.key] ?: return false
+ return (mSystemClock.currentTimeMillis() - updateTime) <= MAX_RANKING_UPDATE_DELAY_MS
+ }
+
+ private fun cleanUpEntryUpdateTimes() {
+ // Because we won't update entries that are older than this amount of time anyway, clean
+ // up any entries that are too old to notify.
+ val toRemove = ArraySet<String>()
+ for ((key, updateTime) in mEntriesUpdateTimes) {
+ if (updateTime == null ||
+ (mSystemClock.currentTimeMillis() - updateTime) > MAX_RANKING_UPDATE_DELAY_MS) {
+ toRemove.add(key)
+ }
+ }
+ mEntriesUpdateTimes.removeAll(toRemove)
+ }
+
/** When an action is pressed on a notification, end HeadsUp lifetime extension. */
private val mActionPressListener = Consumer<NotificationEntry> { entry ->
if (mNotifsExtendingLifetime.contains(entry)) {
@@ -597,6 +650,9 @@
companion object {
private const val TAG = "HeadsUpCoordinator"
private const val BIND_TIMEOUT = 1000L
+
+ // This value is set to match MAX_SOUND_DELAY_MS in NotificationRecord.
+ private const val MAX_RANKING_UPDATE_DELAY_MS: Long = 2000
}
data class PostedEntry(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index fa7bfae..2180d89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -455,6 +455,9 @@
void collapseShade();
+ /** Collapse the shade, but conditional on a flag specific to the trigger of a bugreport. */
+ void collapseShadeForBugreport();
+
int getWakefulnessState();
boolean isScreenFullyOff();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 604e146..489a199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -885,6 +885,11 @@
mBubblesOptional.get().setExpandListener(mBubbleExpandListener);
}
+ // Do not restart System UI when the bugreport flag changes.
+ mFeatureFlags.addListener(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT, event -> {
+ event.requestNoRestart();
+ });
+
mStatusBarSignalPolicy.init();
mKeyguardIndicationController.init();
@@ -3580,6 +3585,13 @@
}
}
+ @Override
+ public void collapseShadeForBugreport() {
+ if (!mFeatureFlags.isEnabled(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT)) {
+ collapseShade();
+ }
+ }
+
@VisibleForTesting
final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitchController.java
index 00c3e8f..5e2a7c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitchController.java
@@ -26,6 +26,7 @@
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.Expandable;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.ActivityStarter;
@@ -67,7 +68,7 @@
ActivityLaunchAnimator.Controller.fromView(v, null),
true /* showOverlockscreenwhenlocked */, UserHandle.SYSTEM);
} else {
- mUserSwitchDialogController.showDialog(v);
+ mUserSwitchDialogController.showDialog(v.getContext(), Expandable.fromView(v));
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
index 0d52f46..e498ae4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
@@ -19,6 +19,7 @@
import android.content.Intent
import android.os.UserHandle
import android.view.View
+import com.android.systemui.animation.Expandable
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.plugins.ActivityStarter
@@ -75,7 +76,7 @@
null /* ActivityLaunchAnimator.Controller */,
true /* showOverlockscreenwhenlocked */, UserHandle.SYSTEM)
} else {
- userSwitcherDialogController.showDialog(view)
+ userSwitcherDialogController.showDialog(view.context, Expandable.fromView(view))
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
index dc73d1f..f63d652 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java
@@ -36,6 +36,7 @@
import com.android.keyguard.dagger.KeyguardUserSwitcherScope;
import com.android.settingslib.drawable.CircleFramedDrawable;
import com.android.systemui.R;
+import com.android.systemui.animation.Expandable;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -190,7 +191,8 @@
mUiEventLogger.log(
LockscreenGestureLogger.LockscreenUiEvent.LOCKSCREEN_SWITCH_USER_TAP);
- mUserSwitchDialogController.showDialog(mUserAvatarViewWithBackground);
+ mUserSwitchDialogController.showDialog(mUserAvatarViewWithBackground.getContext(),
+ Expandable.fromView(mUserAvatarViewWithBackground));
});
mUserAvatarView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/Condition.java b/packages/SystemUI/src/com/android/systemui/util/condition/Condition.java
index ecb365f..2c317dd 100644
--- a/packages/SystemUI/src/com/android/systemui/util/condition/Condition.java
+++ b/packages/SystemUI/src/com/android/systemui/util/condition/Condition.java
@@ -172,10 +172,14 @@
return Boolean.TRUE.equals(mIsConditionMet);
}
- private boolean shouldLog() {
+ protected final boolean shouldLog() {
return Log.isLoggable(mTag, Log.DEBUG);
}
+ protected final String getTag() {
+ return mTag;
+ }
+
/**
* Callback that receives updates about whether the condition has been fulfilled.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
index 4824f67..cb430ba 100644
--- a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
@@ -117,6 +117,7 @@
final SubscriptionState state = new SubscriptionState(subscription);
mExecutor.execute(() -> {
+ if (shouldLog()) Log.d(mTag, "adding subscription");
mSubscriptions.put(token, state);
// Add and associate conditions.
@@ -143,7 +144,7 @@
*/
public void removeSubscription(@NotNull Subscription.Token token) {
mExecutor.execute(() -> {
- if (shouldLog()) Log.d(mTag, "removing callback");
+ if (shouldLog()) Log.d(mTag, "removing subscription");
if (!mSubscriptions.containsKey(token)) {
Log.e(mTag, "subscription not present:" + token);
return;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 1c686c6..5e9c1aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -22,7 +22,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -52,6 +51,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.systemui.R;
@@ -97,6 +97,7 @@
private static final int DEFAULT_ICON_ID = R.drawable.ic_info_outline;
private ViewGroup mRootView;
+ private ViewGroup mSecurityFooterView;
private TextView mFooterText;
private TestableImageView mPrimaryFooterIcon;
private QSSecurityFooter mFooter;
@@ -121,21 +122,26 @@
Looper looper = mTestableLooper.getLooper();
Handler mainHandler = new Handler(looper);
when(mUserTracker.getUserInfo()).thenReturn(mock(UserInfo.class));
- mRootView = (ViewGroup) new LayoutInflaterBuilder(mContext)
+ mSecurityFooterView = (ViewGroup) new LayoutInflaterBuilder(mContext)
.replace("ImageView", TestableImageView.class)
.build().inflate(R.layout.quick_settings_security_footer, null, false);
mFooterUtils = new QSSecurityFooterUtils(getContext(),
getContext().getSystemService(DevicePolicyManager.class), mUserTracker,
mainHandler, mActivityStarter, mSecurityController, looper, mDialogLaunchAnimator);
- mFooter = new QSSecurityFooter(mRootView, mainHandler, mSecurityController, looper,
- mBroadcastDispatcher, mFooterUtils);
- mFooterText = mRootView.findViewById(R.id.footer_text);
- mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
+ mFooter = new QSSecurityFooter(mSecurityFooterView, mainHandler, mSecurityController,
+ looper, mBroadcastDispatcher, mFooterUtils);
+ mFooterText = mSecurityFooterView.findViewById(R.id.footer_text);
+ mPrimaryFooterIcon = mSecurityFooterView.findViewById(R.id.primary_footer_icon);
when(mSecurityController.getDeviceOwnerComponentOnAnyUser())
.thenReturn(DEVICE_OWNER_COMPONENT);
when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
.thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
+
+ // mSecurityFooterView must have a ViewGroup parent so that
+ // DialogLaunchAnimator.Controller.fromView() does not return null.
+ mRootView = new FrameLayout(mContext);
+ mRootView.addView(mSecurityFooterView);
ViewUtils.attachView(mRootView);
mFooter.init();
@@ -153,7 +159,7 @@
mFooter.refreshState();
TestableLooper.get(this).processAllMessages();
- assertEquals(View.GONE, mRootView.getVisibility());
+ assertEquals(View.GONE, mSecurityFooterView.getVisibility());
}
@Test
@@ -165,7 +171,7 @@
TestableLooper.get(this).processAllMessages();
assertEquals(mContext.getString(R.string.quick_settings_disclosure_management),
mFooterText.getText());
- assertEquals(View.VISIBLE, mRootView.getVisibility());
+ assertEquals(View.VISIBLE, mSecurityFooterView.getVisibility());
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
}
@@ -181,7 +187,7 @@
assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management,
MANAGING_ORGANIZATION),
mFooterText.getText());
- assertEquals(View.VISIBLE, mRootView.getVisibility());
+ assertEquals(View.VISIBLE, mSecurityFooterView.getVisibility());
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
}
@@ -200,7 +206,7 @@
assertEquals(mContext.getString(
R.string.quick_settings_financed_disclosure_named_management,
MANAGING_ORGANIZATION), mFooterText.getText());
- assertEquals(View.VISIBLE, mRootView.getVisibility());
+ assertEquals(View.VISIBLE, mSecurityFooterView.getVisibility());
assertEquals(View.VISIBLE, mPrimaryFooterIcon.getVisibility());
assertEquals(DEFAULT_ICON_ID, mPrimaryFooterIcon.getLastImageResource());
}
@@ -217,7 +223,7 @@
mFooter.refreshState();
TestableLooper.get(this).processAllMessages();
- assertEquals(View.GONE, mRootView.getVisibility());
+ assertEquals(View.GONE, mSecurityFooterView.getVisibility());
}
@Test
@@ -227,8 +233,8 @@
mFooter.refreshState();
TestableLooper.get(this).processAllMessages();
- assertFalse(mRootView.isClickable());
- assertEquals(View.GONE, mRootView.findViewById(R.id.footer_icon).getVisibility());
+ assertFalse(mSecurityFooterView.isClickable());
+ assertEquals(View.GONE, mSecurityFooterView.findViewById(R.id.footer_icon).getVisibility());
}
@Test
@@ -241,8 +247,9 @@
mFooter.refreshState();
TestableLooper.get(this).processAllMessages();
- assertTrue(mRootView.isClickable());
- assertEquals(View.VISIBLE, mRootView.findViewById(R.id.footer_icon).getVisibility());
+ assertTrue(mSecurityFooterView.isClickable());
+ assertEquals(View.VISIBLE,
+ mSecurityFooterView.findViewById(R.id.footer_icon).getVisibility());
}
@Test
@@ -254,8 +261,8 @@
mFooter.refreshState();
TestableLooper.get(this).processAllMessages();
- assertFalse(mRootView.isClickable());
- assertEquals(View.GONE, mRootView.findViewById(R.id.footer_icon).getVisibility());
+ assertFalse(mSecurityFooterView.isClickable());
+ assertEquals(View.GONE, mSecurityFooterView.findViewById(R.id.footer_icon).getVisibility());
}
@Test
@@ -734,11 +741,11 @@
@Test
public void testDialogUsesDialogLauncher() {
when(mSecurityController.isDeviceManaged()).thenReturn(true);
- mFooter.onClick(mRootView);
+ mFooter.onClick(mSecurityFooterView);
mTestableLooper.processAllMessages();
- verify(mDialogLaunchAnimator).showFromView(any(), eq(mRootView), any());
+ verify(mDialogLaunchAnimator).show(any(), any());
}
@Test
@@ -775,7 +782,7 @@
ArgumentCaptor<AlertDialog> dialogCaptor = ArgumentCaptor.forClass(AlertDialog.class);
mTestableLooper.processAllMessages();
- verify(mDialogLaunchAnimator).showFromView(dialogCaptor.capture(), any(), any());
+ verify(mDialogLaunchAnimator).show(dialogCaptor.capture(), any());
AlertDialog dialog = dialogCaptor.getValue();
dialog.create();
@@ -817,8 +824,8 @@
verify(mBroadcastDispatcher).registerReceiverWithHandler(captor.capture(), any(), any(),
any());
- // Pretend view is not visible temporarily
- mRootView.onVisibilityAggregated(false);
+ // Pretend view is not attached anymore.
+ mRootView.removeView(mSecurityFooterView);
captor.getValue().onReceive(mContext,
new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG));
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractorTest.kt
index 3c25807..2c2ddbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/footer/domain/interactor/FooterActionsInteractorTest.kt
@@ -23,13 +23,13 @@
import android.provider.Settings
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
-import android.view.View
import androidx.test.filters.SmallTest
import com.android.internal.logging.nano.MetricsProto
import com.android.internal.logging.testing.FakeMetricsLogger
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ActivityLaunchAnimator
+import com.android.systemui.animation.Expandable
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.globalactions.GlobalActionsDialogLite
@@ -70,13 +70,13 @@
val underTest = utils.footerActionsInteractor(qsSecurityFooterUtils = qsSecurityFooterUtils)
val quickSettingsContext = mock<Context>()
- underTest.showDeviceMonitoringDialog(quickSettingsContext)
+
+ underTest.showDeviceMonitoringDialog(quickSettingsContext, null)
verify(qsSecurityFooterUtils).showDeviceMonitoringDialog(quickSettingsContext, null)
- val view = mock<View>()
- whenever(view.context).thenReturn(quickSettingsContext)
- underTest.showDeviceMonitoringDialog(view)
- verify(qsSecurityFooterUtils).showDeviceMonitoringDialog(quickSettingsContext, null)
+ val expandable = mock<Expandable>()
+ underTest.showDeviceMonitoringDialog(quickSettingsContext, expandable)
+ verify(qsSecurityFooterUtils).showDeviceMonitoringDialog(quickSettingsContext, expandable)
}
@Test
@@ -85,8 +85,8 @@
val underTest = utils.footerActionsInteractor(uiEventLogger = uiEventLogger)
val globalActionsDialogLite = mock<GlobalActionsDialogLite>()
- val view = mock<View>()
- underTest.showPowerMenuDialog(globalActionsDialogLite, view)
+ val expandable = mock<Expandable>()
+ underTest.showPowerMenuDialog(globalActionsDialogLite, expandable)
// Event is logged.
val logs = uiEventLogger.logs
@@ -99,7 +99,7 @@
.showOrHideDialog(
/* keyguardShowing= */ false,
/* isDeviceProvisioned= */ true,
- view,
+ expandable,
)
}
@@ -167,11 +167,11 @@
userSwitchDialogController = userSwitchDialogController,
)
- val view = mock<View>()
- underTest.showUserSwitcher(view)
+ val expandable = mock<Expandable>()
+ underTest.showUserSwitcher(context, expandable)
// Dialog is shown.
- verify(userSwitchDialogController).showDialog(view)
+ verify(userSwitchDialogController).showDialog(context, expandable)
}
@Test
@@ -184,12 +184,9 @@
activityStarter = activityStarter,
)
- // The clicked view. The context is necessary because it's used to build the intent, that
- // we check below.
- val view = mock<View>()
- whenever(view.context).thenReturn(context)
-
- underTest.showUserSwitcher(view)
+ // The clicked expandable.
+ val expandable = mock<Expandable>()
+ underTest.showUserSwitcher(context, expandable)
// Dialog is shown.
val intentCaptor = argumentCaptor<Intent>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
index 9d908fd..0a34810 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
@@ -20,12 +20,12 @@
import android.content.Intent
import android.provider.Settings
import android.testing.AndroidTestingRunner
-import android.view.View
import android.widget.Button
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.animation.Expandable
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.PseudoGridView
@@ -35,6 +35,7 @@
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -63,7 +64,7 @@
@Mock
private lateinit var userDetailViewAdapter: UserDetailView.Adapter
@Mock
- private lateinit var launchView: View
+ private lateinit var launchExpandable: Expandable
@Mock
private lateinit var neutralButton: Button
@Mock
@@ -79,7 +80,6 @@
fun setUp() {
MockitoAnnotations.initMocks(this)
- `when`(launchView.context).thenReturn(mContext)
`when`(dialog.context).thenReturn(mContext)
controller = UserSwitchDialogController(
@@ -94,32 +94,34 @@
@Test
fun showDialog_callsDialogShow() {
- controller.showDialog(launchView)
- verify(dialogLaunchAnimator).showFromView(eq(dialog), eq(launchView), any(), anyBoolean())
+ val launchController = mock<DialogLaunchAnimator.Controller>()
+ `when`(launchExpandable.dialogLaunchController(any())).thenReturn(launchController)
+ controller.showDialog(context, launchExpandable)
+ verify(dialogLaunchAnimator).show(eq(dialog), eq(launchController), anyBoolean())
verify(uiEventLogger).log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
}
@Test
fun dialog_showForAllUsers() {
- controller.showDialog(launchView)
+ controller.showDialog(context, launchExpandable)
verify(dialog).setShowForAllUsers(true)
}
@Test
fun dialog_cancelOnTouchOutside() {
- controller.showDialog(launchView)
+ controller.showDialog(context, launchExpandable)
verify(dialog).setCanceledOnTouchOutside(true)
}
@Test
fun adapterAndGridLinked() {
- controller.showDialog(launchView)
+ controller.showDialog(context, launchExpandable)
verify(userDetailViewAdapter).linkToViewGroup(any<PseudoGridView>())
}
@Test
fun doneButtonLogsCorrectly() {
- controller.showDialog(launchView)
+ controller.showDialog(context, launchExpandable)
verify(dialog).setPositiveButton(anyInt(), capture(clickCaptor))
@@ -132,7 +134,7 @@
fun clickSettingsButton_noFalsing_opensSettings() {
`when`(falsingManager.isFalseTap(anyInt())).thenReturn(false)
- controller.showDialog(launchView)
+ controller.showDialog(context, launchExpandable)
verify(dialog)
.setNeutralButton(anyInt(), capture(clickCaptor), eq(false) /* dismissOnClick */)
@@ -153,7 +155,7 @@
fun clickSettingsButton_Falsing_notOpensSettings() {
`when`(falsingManager.isFalseTap(anyInt())).thenReturn(true)
- controller.showDialog(launchView)
+ controller.showDialog(context, launchExpandable)
verify(dialog)
.setNeutralButton(anyInt(), capture(clickCaptor), eq(false) /* dismissOnClick */)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 340bc96..3ff7639 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -674,7 +674,9 @@
@Test
fun testOnRankingApplied_newEntryShouldAlert() {
// GIVEN that mEntry has never interrupted in the past, and now should
+ // and is new enough to do so
assertFalse(mEntry.hasInterrupted())
+ mCoordinator.setUpdateTime(mEntry, mSystemClock.currentTimeMillis())
setShouldHeadsUp(mEntry)
whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry))
@@ -690,8 +692,9 @@
@Test
fun testOnRankingApplied_alreadyAlertedEntryShouldNotAlertAgain() {
- // GIVEN that mEntry has alerted in the past
+ // GIVEN that mEntry has alerted in the past, even if it's new
mEntry.setInterruption()
+ mCoordinator.setUpdateTime(mEntry, mSystemClock.currentTimeMillis())
setShouldHeadsUp(mEntry)
whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry))
@@ -725,6 +728,27 @@
verify(mHeadsUpManager).showNotification(mEntry)
}
+ @Test
+ fun testOnRankingApplied_entryUpdatedButTooOld() {
+ // GIVEN that mEntry is added in a state where it should not HUN
+ setShouldHeadsUp(mEntry, false)
+ mCollectionListener.onEntryAdded(mEntry)
+
+ // and it was actually added 10s ago
+ mCoordinator.setUpdateTime(mEntry, mSystemClock.currentTimeMillis() - 10000)
+
+ // WHEN it is updated to HUN and then a ranking update occurs
+ setShouldHeadsUp(mEntry)
+ whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry))
+ mCollectionListener.onRankingApplied()
+ mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry))
+ mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry))
+
+ // THEN the notification is never bound or shown
+ verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any())
+ verify(mHeadsUpManager, never()).showNotification(any())
+ }
+
private fun setShouldHeadsUp(entry: NotificationEntry, should: Boolean = true) {
whenever(mNotificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(should)
whenever(mNotificationInterruptStateProvider.checkHeadsUp(eq(entry), any()))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index ad497a2..d4cd4a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -98,7 +98,8 @@
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -271,7 +272,6 @@
@Mock private OngoingCallController mOngoingCallController;
@Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
@Mock private LockscreenShadeTransitionController mLockscreenTransitionController;
- @Mock private FeatureFlags mFeatureFlags;
@Mock private NotificationVisibilityProvider mVisibilityProvider;
@Mock private WallpaperManager mWallpaperManager;
@Mock private IWallpaperManager mIWallpaperManager;
@@ -296,9 +296,10 @@
private ShadeController mShadeController;
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
- private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
- private FakeExecutor mUiBgExecutor = new FakeExecutor(mFakeSystemClock);
- private InitController mInitController = new InitController();
+ private final FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
+ private final FakeExecutor mUiBgExecutor = new FakeExecutor(mFakeSystemClock);
+ private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
+ private final InitController mInitController = new InitController();
private final DumpManager mDumpManager = new DumpManager();
@Before
@@ -1017,6 +1018,60 @@
}
@Test
+ public void collapseShade_callsAnimateCollapsePanels_whenExpanded() {
+ // GIVEN the shade is expanded
+ mCentralSurfaces.setPanelExpanded(true);
+ mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+
+ // WHEN collapseShade is called
+ mCentralSurfaces.collapseShade();
+
+ // VERIFY that animateCollapsePanels is called
+ verify(mShadeController).animateCollapsePanels();
+ }
+
+ @Test
+ public void collapseShade_doesNotCallAnimateCollapsePanels_whenCollapsed() {
+ // GIVEN the shade is collapsed
+ mCentralSurfaces.setPanelExpanded(false);
+ mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+
+ // WHEN collapseShade is called
+ mCentralSurfaces.collapseShade();
+
+ // VERIFY that animateCollapsePanels is NOT called
+ verify(mShadeController, never()).animateCollapsePanels();
+ }
+
+ @Test
+ public void collapseShadeForBugReport_callsAnimateCollapsePanels_whenFlagDisabled() {
+ // GIVEN the shade is expanded & flag enabled
+ mCentralSurfaces.setPanelExpanded(true);
+ mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mFeatureFlags.set(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT, false);
+
+ // WHEN collapseShadeForBugreport is called
+ mCentralSurfaces.collapseShadeForBugreport();
+
+ // VERIFY that animateCollapsePanels is called
+ verify(mShadeController).animateCollapsePanels();
+ }
+
+ @Test
+ public void collapseShadeForBugReport_doesNotCallAnimateCollapsePanels_whenFlagEnabled() {
+ // GIVEN the shade is expanded & flag enabled
+ mCentralSurfaces.setPanelExpanded(true);
+ mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
+ mFeatureFlags.set(Flags.LEAVE_SHADE_OPEN_FOR_BUGREPORT, true);
+
+ // WHEN collapseShadeForBugreport is called
+ mCentralSurfaces.collapseShadeForBugreport();
+
+ // VERIFY that animateCollapsePanels is called
+ verify(mShadeController, never()).animateCollapsePanels();
+ }
+
+ @Test
public void deviceStateChange_unfolded_shadeOpen_setsLeaveOpenOnKeyguardHide() {
when(mKeyguardStateController.isShowing()).thenReturn(false);
setFoldedStates(FOLD_STATE_FOLDED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt
index bf43238..eba3b04 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt
@@ -20,7 +20,6 @@
import android.os.UserHandle
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
-import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
@@ -34,8 +33,8 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -91,7 +90,7 @@
fun testStartActivity() {
`when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(false)
statusBarUserSwitcherContainer.callOnClick()
- verify(userSwitcherDialogController).showDialog(any(View::class.java))
+ verify(userSwitcherDialogController).showDialog(any(), any())
`when`(featureFlags.isEnabled(Flags.FULL_SCREEN_USER_SWITCHER)).thenReturn(true)
statusBarUserSwitcherContainer.callOnClick()
verify(activityStarter).startActivity(any(Intent::class.java),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeFgsManagerController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeFgsManagerController.kt
index 5272585..c33ce5d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeFgsManagerController.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/FakeFgsManagerController.kt
@@ -16,7 +16,7 @@
package com.android.systemui.qs
-import android.view.View
+import com.android.systemui.animation.Expandable
import com.android.systemui.qs.FgsManagerController.OnDialogDismissedListener
import com.android.systemui.qs.FgsManagerController.OnNumberOfPackagesChangedListener
import kotlinx.coroutines.flow.MutableStateFlow
@@ -54,7 +54,7 @@
override fun init() {}
- override fun showDialog(viewLaunchedFrom: View?) {}
+ override fun showDialog(expandable: Expandable?) {}
override fun addOnNumberOfPackagesChangedListener(listener: OnNumberOfPackagesChangedListener) {
numRunningPackagesListeners.add(listener)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
index 2a9aedd..325da4e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt
@@ -57,7 +57,6 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.settings.GlobalSettings
-import com.android.systemui.util.time.FakeSystemClock
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineDispatcher
@@ -68,7 +67,6 @@
class FooterActionsTestUtils(
private val context: Context,
private val testableLooper: TestableLooper,
- private val fakeClock: FakeSystemClock = FakeSystemClock(),
) {
/** Enable or disable the user switcher in the settings. */
fun setUserSwitcherEnabled(settings: GlobalSettings, enabled: Boolean, userId: Int) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index fd1fdce..a55b118 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -61,6 +61,7 @@
import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.MATCH_ALL;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -10633,10 +10634,18 @@
private final ArraySet<ManagedServiceInfo> mLightTrimListeners = new ArraySet<>();
ArrayMap<Pair<ComponentName, Integer>, NotificationListenerFilter>
mRequestedNotificationListeners = new ArrayMap<>();
+ private final boolean mIsHeadlessSystemUserMode;
public NotificationListeners(Context context, Object lock, UserProfiles userProfiles,
IPackageManager pm) {
+ this(context, lock, userProfiles, pm, UserManager.isHeadlessSystemUserMode());
+ }
+
+ @VisibleForTesting
+ public NotificationListeners(Context context, Object lock, UserProfiles userProfiles,
+ IPackageManager pm, boolean isHeadlessSystemUserMode) {
super(context, lock, userProfiles, pm);
+ this.mIsHeadlessSystemUserMode = isHeadlessSystemUserMode;
}
@Override
@@ -10661,10 +10670,16 @@
if (TextUtils.isEmpty(listeners[i])) {
continue;
}
+ int packageQueryFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
+ // In the headless system user mode, packages might not be installed for the
+ // system user. Match packages for any user since apps can be installed only for
+ // non-system users and would be considering uninstalled for the system user.
+ if (mIsHeadlessSystemUserMode) {
+ packageQueryFlags += MATCH_ANY_USER;
+ }
ArraySet<ComponentName> approvedListeners =
- this.queryPackageForServices(listeners[i],
- MATCH_DIRECT_BOOT_AWARE
- | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM);
+ this.queryPackageForServices(listeners[i], packageQueryFlags,
+ USER_SYSTEM);
for (int k = 0; k < approvedListeners.size(); k++) {
ComponentName cn = approvedListeners.valueAt(k);
addDefaultComponentOrPackage(cn.flattenToString());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
index c5131c8..101a5cb 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -15,6 +15,7 @@
*/
package com.android.server.notification;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
@@ -30,9 +31,11 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.intThat;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -49,6 +52,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.pm.VersionedPackage;
+import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.NotificationListenerFilter;
@@ -69,6 +73,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.internal.util.reflection.FieldSetter;
@@ -77,6 +82,7 @@
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
import java.util.List;
public class NotificationListenersTest extends UiServiceTestCase {
@@ -85,6 +91,8 @@
private PackageManager mPm;
@Mock
private IPackageManager miPm;
+ @Mock
+ private Resources mResources;
@Mock
NotificationManagerService mNm;
@@ -96,7 +104,8 @@
private ComponentName mCn1 = new ComponentName("pkg", "pkg.cmp");
private ComponentName mCn2 = new ComponentName("pkg2", "pkg2.cmp2");
-
+ private ComponentName mUninstalledComponent = new ComponentName("pkg3",
+ "pkg3.NotificationListenerService");
@Before
public void setUp() throws Exception {
@@ -111,7 +120,7 @@
@Test
public void testReadExtraTag() throws Exception {
- String xml = "<" + TAG_REQUESTED_LISTENERS+ ">"
+ String xml = "<" + TAG_REQUESTED_LISTENERS + ">"
+ "<listener component=\"" + mCn1.flattenToString() + "\" user=\"0\">"
+ "<allowed types=\"7\" />"
+ "</listener>"
@@ -131,11 +140,55 @@
}
@Test
+ public void loadDefaultsFromConfig_forHeadlessSystemUser_loadUninstalled() throws Exception {
+ // setup with headless system user mode
+ mListeners = spy(mNm.new NotificationListeners(
+ mContext, new Object(), mock(ManagedServices.UserProfiles.class), miPm,
+ /* isHeadlessSystemUserMode= */ true));
+ mockDefaultListenerConfigForUninstalledComponent(mUninstalledComponent);
+
+ mListeners.loadDefaultsFromConfig();
+
+ assertThat(mListeners.getDefaultComponents()).contains(mUninstalledComponent);
+ }
+
+ @Test
+ public void loadDefaultsFromConfig_forNonHeadlessSystemUser_ignoreUninstalled()
+ throws Exception {
+ // setup without headless system user mode
+ mListeners = spy(mNm.new NotificationListeners(
+ mContext, new Object(), mock(ManagedServices.UserProfiles.class), miPm,
+ /* isHeadlessSystemUserMode= */ false));
+ mockDefaultListenerConfigForUninstalledComponent(mUninstalledComponent);
+
+ mListeners.loadDefaultsFromConfig();
+
+ assertThat(mListeners.getDefaultComponents()).doesNotContain(mUninstalledComponent);
+ }
+
+ private void mockDefaultListenerConfigForUninstalledComponent(ComponentName componentName) {
+ ArraySet<ComponentName> components = new ArraySet<>(Arrays.asList(componentName));
+ when(mResources
+ .getString(
+ com.android.internal.R.string.config_defaultListenerAccessPackages))
+ .thenReturn(componentName.getPackageName());
+ when(mContext.getResources()).thenReturn(mResources);
+ doReturn(components).when(mListeners).queryPackageForServices(
+ eq(componentName.getPackageName()),
+ intThat(hasIntBitFlag(MATCH_ANY_USER)),
+ anyInt());
+ }
+
+ public static ArgumentMatcher<Integer> hasIntBitFlag(int flag) {
+ return arg -> arg != null && ((arg & flag) == flag);
+ }
+
+ @Test
public void testWriteExtraTag() throws Exception {
NotificationListenerFilter nlf = new NotificationListenerFilter(7, new ArraySet<>());
VersionedPackage a1 = new VersionedPackage("pkg1", 243);
NotificationListenerFilter nlf2 =
- new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[] {a1}));
+ new NotificationListenerFilter(4, new ArraySet<>(new VersionedPackage[]{a1}));
mListeners.setNotificationListenerFilter(Pair.create(mCn1, 0), nlf);
mListeners.setNotificationListenerFilter(Pair.create(mCn2, 10), nlf2);