diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-07 02:20:53 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-01-07 02:20:53 +0000 |
commit | b0e0f22f629857555e40e7a2d47b8a5536321909 (patch) | |
tree | a039eb7a444c66fd6452dd24519742bc0df0fc8c | |
parent | e8b6677f888afd363d166a9364765afe0e151f1e (diff) | |
parent | c956023fe65b8deaf126b14aafa8541572b0a404 (diff) | |
download | base-b0e0f22f629857555e40e7a2d47b8a5536321909.tar.gz |
Snap for 9463735 from c956023fe65b8deaf126b14aafa8541572b0a404 to tm-qpr2-release
Change-Id: I1b1f0cbb1eed5c29db6b3ce12a6774bcdbe0568b
147 files changed, 2064 insertions, 323 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 8e09939f6805..4a4ba6371939 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1128,6 +1128,9 @@ public class DevicePolicyManager { * <p>Use only for device owner provisioning. This extra can be returned by the admin app when * performing the admin-integrated provisioning flow as a result of the {@link * #ACTION_GET_PROVISIONING_MODE} activity. + * + * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE"; @@ -1139,6 +1142,9 @@ public class DevicePolicyManager { * <p>Use only for device owner provisioning. This extra can be returned by the admin app when * performing the admin-integrated provisioning flow as a result of the {@link * #ACTION_GET_PROVISIONING_MODE} activity. + * + * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME"; @@ -1150,6 +1156,9 @@ public class DevicePolicyManager { * <p>Use only for device owner provisioning. This extra can be returned by the admin app when * performing the admin-integrated provisioning flow as a result of the {@link * #ACTION_GET_PROVISIONING_MODE} activity. + * + * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE"; @@ -1159,7 +1168,7 @@ public class DevicePolicyManager { * owner provisioning for downloading the mobile device management application. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_SSID = "android.app.extra.PROVISIONING_WIFI_SSID"; @@ -1169,7 +1178,7 @@ public class DevicePolicyManager { * is hidden or not. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN"; @@ -1180,7 +1189,7 @@ public class DevicePolicyManager { * {@code WEP} or {@code EAP}. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE"; @@ -1190,7 +1199,7 @@ public class DevicePolicyManager { * {@link #EXTRA_PROVISIONING_WIFI_SSID}. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_PASSWORD = "android.app.extra.PROVISIONING_WIFI_PASSWORD"; @@ -1281,7 +1290,7 @@ public class DevicePolicyManager { * {@link #EXTRA_PROVISIONING_WIFI_SSID}. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_PROXY_HOST = "android.app.extra.PROVISIONING_WIFI_PROXY_HOST"; @@ -1291,7 +1300,7 @@ public class DevicePolicyManager { * {@link #EXTRA_PROVISIONING_WIFI_SSID}. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_PROXY_PORT = "android.app.extra.PROVISIONING_WIFI_PROXY_PORT"; @@ -1301,7 +1310,7 @@ public class DevicePolicyManager { * {@link #EXTRA_PROVISIONING_WIFI_SSID}. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_PROXY_BYPASS = "android.app.extra.PROVISIONING_WIFI_PROXY_BYPASS"; @@ -1311,7 +1320,7 @@ public class DevicePolicyManager { * {@link #EXTRA_PROVISIONING_WIFI_SSID}. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_WIFI_PAC_URL = "android.app.extra.PROVISIONING_WIFI_PAC_URL"; @@ -1321,7 +1330,7 @@ public class DevicePolicyManager { * package. When not provided it is assumed that the device admin package is already installed. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION"; @@ -1401,7 +1410,7 @@ public class DevicePolicyManager { * installed package is less than this version code. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE = "android.app.extra.PROVISIONING_DEVICE_ADMIN_MINIMUM_VERSION_CODE"; @@ -1411,7 +1420,7 @@ public class DevicePolicyManager { * url specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER"; @@ -1426,7 +1435,7 @@ public class DevicePolicyManager { * be asked to factory reset the device. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. * * <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP} * and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported. @@ -1472,7 +1481,7 @@ public class DevicePolicyManager { * the user will be asked to factory reset the device. * * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner - * provisioning via an NFC bump. + * provisioning via an NFC bump. It can also be used for QR code provisioning. */ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM"; diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java index 43d427db2c75..4c49f2c049ee 100644 --- a/core/java/android/view/WindowManagerPolicyConstants.java +++ b/core/java/android/view/WindowManagerPolicyConstants.java @@ -169,6 +169,9 @@ public interface WindowManagerPolicyConstants { case PowerManager.WAKE_REASON_POWER_BUTTON: case PowerManager.WAKE_REASON_PLUGGED_IN: case PowerManager.WAKE_REASON_GESTURE: + case PowerManager.WAKE_REASON_TAP: + case PowerManager.WAKE_REASON_LIFT: + case PowerManager.WAKE_REASON_BIOMETRIC: case PowerManager.WAKE_REASON_CAMERA_LAUNCH: case PowerManager.WAKE_REASON_WAKE_KEY: case PowerManager.WAKE_REASON_WAKE_MOTION: diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java index 9152e7837b82..a0bd7f70ca58 100644 --- a/core/java/android/window/ImeOnBackInvokedDispatcher.java +++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java @@ -220,16 +220,14 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc * @param previous the previously focused {@link ViewRootImpl}. * @param current the currently focused {@link ViewRootImpl}. */ - // TODO(b/232845902): Add CTS to test IME back behavior when there's root view change while - // IME is up. public void switchRootView(ViewRootImpl previous, ViewRootImpl current) { for (ImeOnBackInvokedCallback imeCallback : mImeCallbacks) { if (previous != null) { previous.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(imeCallback); } if (current != null) { - current.getOnBackInvokedDispatcher().registerOnBackInvokedCallback( - imeCallback.mPriority, imeCallback); + current.getOnBackInvokedDispatcher().registerOnBackInvokedCallbackUnchecked( + imeCallback, imeCallback.mPriority); } } } diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index eece25d707c5..ea61feaab93a 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -327,7 +327,7 @@ <string name="permgrouplab_phone" msgid="570318944091926620">"Telefon"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"uskutečňování a spravování telefonních hovorů"</string> <string name="permgrouplab_sensors" msgid="9134046949784064495">"Tělesné senzory"</string> - <string name="permgroupdesc_sensors" msgid="2610631290633747752">"přístup k datům ze snímačů vašich životních funkcí"</string> + <string name="permgroupdesc_sensors" msgid="2610631290633747752">"přístup k datům ze senzorů vašich životních funkcí"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"Oznámení"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"zobrazovat oznámení"</string> <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Načítat obsah oken"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 64d390e093f1..876d3a17aae3 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1681,13 +1681,13 @@ <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Verknüpfung für Bedienungshilfen aktivieren?"</string> <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Wenn du beide Lautstärketasten einige Sekunden lang gedrückt hältst, aktivierst du die Bedienungshilfen. Dadurch kann sich die Funktionsweise deines Geräts ändern.\n\nAktuelle Funktionen:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nDu kannst ausgewählte Funktionen unter \"Einstellungen\" > \"Bedienungshilfen\" ändern."</string> <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string> - <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Verknüpfung für <xliff:g id="SERVICE">%1$s</xliff:g> aktivieren?"</string> + <string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"Kurzbefehl für <xliff:g id="SERVICE">%1$s</xliff:g> aktivieren?"</string> <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Wenn du beide Lautstärketasten einige Sekunden lang gedrückt hältst, aktivierst du die Bedienungshilfe \"<xliff:g id="SERVICE">%1$s</xliff:g>\". Dadurch kann sich die Funktionsweise deines Geräts ändern.\n\nUnter \"Einstellungen > \"Bedienungshilfen\" kannst du dieser Verknüpfung eine andere Funktion zuweisen."</string> <string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktivieren"</string> <string name="accessibility_shortcut_off" msgid="3651336255403648739">"Nicht aktivieren"</string> <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AN"</string> <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"AUS"</string> - <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> die vollständige Kontrolle über dein Gerät geben?"</string> + <string name="accessibility_enable_service_title" msgid="3931558336268541484">"„<xliff:g id="SERVICE">%1$s</xliff:g>“ die vollständige Kontrolle über dein Gerät geben?"</string> <string name="accessibility_service_warning_description" msgid="291674995220940133">"Die vollständige Kontrolle sollte nur für Apps aktiviert werden, die dir Zugang zu App-Funktionen erleichtern. Das ist in der Regel nur ein kleiner Teil der Apps."</string> <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Bildschirm aufrufen und steuern"</string> <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Die Funktion kann alle Inhalte auf dem Bildschirm lesen und diese Inhalte über andere Apps anzeigen."</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index c4fe972a0b26..c81bf0034a60 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -299,11 +299,11 @@ <string name="user_owner_label" msgid="8628726904184471211">"Vaihda henkilökohtaiseen profiiliin"</string> <string name="managed_profile_label" msgid="7316778766973512382">"Vaihda työprofiiliin"</string> <string name="permgrouplab_contacts" msgid="4254143639307316920">"Yhteystiedot"</string> - <string name="permgroupdesc_contacts" msgid="9163927941244182567">"käyttää yhteystietoja"</string> + <string name="permgroupdesc_contacts" msgid="9163927941244182567">"pääsy yhteystietoihin"</string> <string name="permgrouplab_location" msgid="1858277002233964394">"Sijainti"</string> - <string name="permgroupdesc_location" msgid="1995955142118450685">"käyttää laitteen sijaintia"</string> + <string name="permgroupdesc_location" msgid="1995955142118450685">"pääsy laitteen sijaintiin"</string> <string name="permgrouplab_calendar" msgid="6426860926123033230">"Kalenteri"</string> - <string name="permgroupdesc_calendar" msgid="6762751063361489379">"käyttää kalenteria"</string> + <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pääsy kalenteriin"</string> <string name="permgrouplab_sms" msgid="795737735126084874">"Tekstiviestit"</string> <string name="permgroupdesc_sms" msgid="5726462398070064542">"lähettää ja tarkastella tekstiviestejä"</string> <string name="permgrouplab_storage" msgid="17339216290379241">"Tiedostot"</string> @@ -313,7 +313,7 @@ <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Valokuvat ja videot"</string> <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"pääsy laitteen kuviin ja videoihin"</string> <string name="permgrouplab_microphone" msgid="2480597427667420076">"Mikrofoni"</string> - <string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa ääntä"</string> + <string name="permgroupdesc_microphone" msgid="1047786732792487722">"tallentaa audiota"</string> <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Liikkuminen"</string> <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"nähdä liikkumistietosi"</string> <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string> @@ -325,7 +325,7 @@ <string name="permgrouplab_phone" msgid="570318944091926620">"Puhelin"</string> <string name="permgroupdesc_phone" msgid="270048070781478204">"soittaa ja hallinnoida puheluita"</string> <string name="permgrouplab_sensors" msgid="9134046949784064495">"Kehon anturit"</string> - <string name="permgroupdesc_sensors" msgid="2610631290633747752">"käyttää anturitietoja elintoiminnoistasi"</string> + <string name="permgroupdesc_sensors" msgid="2610631290633747752">"pääsy anturidataan elintoiminnoistasi"</string> <string name="permgrouplab_notifications" msgid="5472972361980668884">"Ilmoitukset"</string> <string name="permgroupdesc_notifications" msgid="4608679556801506580">"näyttää ilmoituksia"</string> <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Noutaa ikkunan sisältöä"</string> @@ -448,7 +448,7 @@ <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Tällä sovelluksella on pääsy sijaintitietoihin milloin tahansa, myös silloin kun sovellusta ei käytetä."</string> <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"muuta ääniasetuksia"</string> <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Antaa sovelluksen muokata yleisiä ääniasetuksia, kuten äänenvoimakkuutta ja käytettävää kaiutinta."</string> - <string name="permlab_recordAudio" msgid="1208457423054219147">"tallentaa ääntä"</string> + <string name="permlab_recordAudio" msgid="1208457423054219147">"tallentaa audiota"</string> <string name="permdesc_recordAudio" msgid="5857246765327514062">"Tämä sovellus voi tallentaa mikrofonilla audiota, kun sovellusta käytetään."</string> <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"tallentaa audiota taustalla"</string> <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Tämä sovellus voi tallentaa mikrofonilla audiota koska tahansa."</string> @@ -1173,7 +1173,7 @@ <string name="selected" msgid="6614607926197755875">"valittu"</string> <string name="not_selected" msgid="410652016565864475">"ei valittu"</string> <string name="in_progress" msgid="2149208189184319441">"käynnissä"</string> - <string name="whichApplication" msgid="5432266899591255759">"Tee toiminto käyttäen sovellusta"</string> + <string name="whichApplication" msgid="5432266899591255759">"Tee toiminto käyttäen:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Suorita sovelluksella %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Suorita toiminto"</string> <string name="whichViewApplication" msgid="5733194231473132945">"Avaa sovelluksessa"</string> @@ -1972,7 +1972,7 @@ <string name="pin_specific_target" msgid="7824671240625957415">"Kiinnitä <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"Irrota"</string> <string name="unpin_specific_target" msgid="3859828252160908146">"Irrota <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="app_info" msgid="6113278084877079851">"Sovelluksen tiedot"</string> + <string name="app_info" msgid="6113278084877079851">"Sovellustiedot"</string> <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="demo_starting_message" msgid="6577581216125805905">"Aloitetaan esittelyä…"</string> <string name="demo_restarting_message" msgid="1160053183701746766">"Palautetaan asetuksia…"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 12015ec6d85f..fb9a3132debe 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1173,7 +1173,7 @@ <string name="selected" msgid="6614607926197755875">"valt"</string> <string name="not_selected" msgid="410652016565864475">"inte valt"</string> <string name="in_progress" msgid="2149208189184319441">"pågår"</string> - <string name="whichApplication" msgid="5432266899591255759">"Slutför åtgärd genom att använda"</string> + <string name="whichApplication" msgid="5432266899591255759">"Slutför åtgärd med"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Slutför åtgärden med %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Slutför åtgärd"</string> <string name="whichViewApplication" msgid="5733194231473132945">"Öppna med"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index f52b714b9563..7cebe2729adb 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -315,7 +315,7 @@ <string name="permgrouplab_microphone" msgid="2480597427667420076">"మైక్రోఫోన్"</string> <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ఆడియోను రికార్డ్ చేయడానికి"</string> <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ఫిజికల్ యాక్టివిటీ"</string> - <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"భౌతిక యాక్టివిటీని యాక్సెస్ చేయండి"</string> + <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ఫిజికల్ యాక్టివిటీని యాక్సెస్ చేయండి"</string> <string name="permgrouplab_camera" msgid="9090413408963547706">"కెమెరా"</string> <string name="permgroupdesc_camera" msgid="7585150538459320326">"చిత్రాలను తీయడానికి మరియు వీడియోను రికార్డ్ చేయడానికి"</string> <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"సమీపంలోని పరికరాలు"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index f7187c466799..2f5efd12a2ba 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -5213,6 +5213,14 @@ having a separating hinge. --> <bool name="config_isDisplayHingeAlwaysSeparating">false</bool> + <!-- Whether enabling rotation compat policy for immersive apps that prevents auto rotation + into non-optimal screen orientation while in fullscreen. This is needed because immersive + apps, such as games, are often not optimized for all orientations and can have a poor UX + when rotated. Additionally, some games rely on sensors for the gameplay so users can + trigger such rotations accidentally when auto rotation is on. + Applicable only if ignoreOrientationRequest is enabled. --> + <bool name="config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled">false</bool> + <!-- Aspect ratio of letterboxing for fixed orientation. Values <= 1.0 will be ignored. Note: Activity min/max aspect ratio restrictions will still be respected. Therefore this override can control the maximum screen area that can be occupied by diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 368ef960f938..41281fa0d40f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4441,6 +4441,7 @@ <java-symbol type="dimen" name="controls_thumbnail_image_max_height" /> <java-symbol type="dimen" name="controls_thumbnail_image_max_width" /> + <java-symbol type="bool" name="config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled" /> <java-symbol type="dimen" name="config_fixedOrientationLetterboxAspectRatio" /> <java-symbol type="dimen" name="config_letterboxBackgroundWallpaperBlurRadius" /> <java-symbol type="integer" name="config_letterboxActivityCornersRadius" /> diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java index fb0a9db6a20b..54edd9ec4335 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java @@ -17,9 +17,13 @@ package androidx.window.extensions; import android.app.ActivityThread; +import android.app.Application; import android.content.Context; +import android.window.TaskFragmentOrganizer; import androidx.annotation.NonNull; +import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; +import androidx.window.common.RawFoldingFeatureProducer; import androidx.window.extensions.area.WindowAreaComponent; import androidx.window.extensions.area.WindowAreaComponentImpl; import androidx.window.extensions.embedding.ActivityEmbeddingComponent; @@ -27,6 +31,8 @@ import androidx.window.extensions.embedding.SplitController; import androidx.window.extensions.layout.WindowLayoutComponent; import androidx.window.extensions.layout.WindowLayoutComponentImpl; +import java.util.Objects; + /** * The reference implementation of {@link WindowExtensions} that implements the initial API version. @@ -34,7 +40,8 @@ import androidx.window.extensions.layout.WindowLayoutComponentImpl; public class WindowExtensionsImpl implements WindowExtensions { private final Object mLock = new Object(); - private volatile WindowLayoutComponent mWindowLayoutComponent; + private volatile DeviceStateManagerFoldingFeatureProducer mFoldingFeatureProducer; + private volatile WindowLayoutComponentImpl mWindowLayoutComponent; private volatile SplitController mSplitController; private volatile WindowAreaComponent mWindowAreaComponent; @@ -44,6 +51,49 @@ public class WindowExtensionsImpl implements WindowExtensions { return 1; } + @NonNull + private Application getApplication() { + return Objects.requireNonNull(ActivityThread.currentApplication()); + } + + @NonNull + private DeviceStateManagerFoldingFeatureProducer getFoldingFeatureProducer() { + if (mFoldingFeatureProducer == null) { + synchronized (mLock) { + if (mFoldingFeatureProducer == null) { + Context context = getApplication(); + RawFoldingFeatureProducer foldingFeatureProducer = + new RawFoldingFeatureProducer(context); + mFoldingFeatureProducer = + new DeviceStateManagerFoldingFeatureProducer(context, + foldingFeatureProducer); + } + } + } + return mFoldingFeatureProducer; + } + + @NonNull + private WindowLayoutComponentImpl getWindowLayoutComponentImpl() { + if (mWindowLayoutComponent == null) { + synchronized (mLock) { + if (mWindowLayoutComponent == null) { + Context context = getApplication(); + DeviceStateManagerFoldingFeatureProducer producer = + getFoldingFeatureProducer(); + // TODO(b/263263909) Use the organizer to tell if an Activity is embededed. + // Need to improve our Dependency Injection and centralize the logic. + TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(command -> { + throw new RuntimeException("Not allowed!"); + }); + mWindowLayoutComponent = new WindowLayoutComponentImpl(context, organizer, + producer); + } + } + } + return mWindowLayoutComponent; + } + /** * Returns a reference implementation of {@link WindowLayoutComponent} if available, * {@code null} otherwise. The implementation must match the API level reported in @@ -52,15 +102,7 @@ public class WindowExtensionsImpl implements WindowExtensions { */ @Override public WindowLayoutComponent getWindowLayoutComponent() { - if (mWindowLayoutComponent == null) { - synchronized (mLock) { - if (mWindowLayoutComponent == null) { - Context context = ActivityThread.currentApplication(); - mWindowLayoutComponent = new WindowLayoutComponentImpl(context); - } - } - } - return mWindowLayoutComponent; + return getWindowLayoutComponentImpl(); } /** @@ -74,7 +116,10 @@ public class WindowExtensionsImpl implements WindowExtensions { if (mSplitController == null) { synchronized (mLock) { if (mSplitController == null) { - mSplitController = new SplitController(); + mSplitController = new SplitController( + getWindowLayoutComponentImpl(), + getFoldingFeatureProducer() + ); } } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 8da591860c2d..1cd3ea5592e3 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -75,8 +75,8 @@ import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.window.common.CommonFoldingFeature; +import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.common.EmptyLifecycleCallbacksAdapter; -import androidx.window.extensions.WindowExtensionsProvider; import androidx.window.extensions.embedding.TransactionManager.TransactionRecord; import androidx.window.extensions.layout.WindowLayoutComponentImpl; @@ -145,19 +145,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen private final Handler mHandler; final Object mLock = new Object(); private final ActivityStartMonitor mActivityStartMonitor; - @NonNull - final WindowLayoutComponentImpl mWindowLayoutComponent; - - public SplitController() { - this((WindowLayoutComponentImpl) Objects.requireNonNull(WindowExtensionsProvider - .getWindowExtensions().getWindowLayoutComponent())); - } - @VisibleForTesting - SplitController(@NonNull WindowLayoutComponentImpl windowLayoutComponent) { + public SplitController(@NonNull WindowLayoutComponentImpl windowLayoutComponent, + @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) { final MainThreadExecutor executor = new MainThreadExecutor(); mHandler = executor.mHandler; - mPresenter = new SplitPresenter(executor, this); + mPresenter = new SplitPresenter(executor, windowLayoutComponent, this); mTransactionManager = new TransactionManager(mPresenter); final ActivityThread activityThread = ActivityThread.currentActivityThread(); final Application application = activityThread.getApplication(); @@ -168,8 +161,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen mActivityStartMonitor = new ActivityStartMonitor(); instrumentation.addMonitor(mActivityStartMonitor); - mWindowLayoutComponent = windowLayoutComponent; - mWindowLayoutComponent.addFoldingStateChangedCallback(new FoldingFeatureListener()); + foldingFeatureProducer.addDataChangedCallback(new FoldingFeatureListener()); } private class FoldingFeatureListener implements Consumer<List<CommonFoldingFeature>> { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index 7b2af4933e66..14d244bbb6ce 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -51,6 +51,7 @@ import androidx.window.extensions.embedding.SplitAttributesCalculator.SplitAttri import androidx.window.extensions.embedding.TaskContainer.TaskProperties; import androidx.window.extensions.layout.DisplayFeature; import androidx.window.extensions.layout.FoldingFeature; +import androidx.window.extensions.layout.WindowLayoutComponentImpl; import androidx.window.extensions.layout.WindowLayoutInfo; import com.android.internal.annotations.VisibleForTesting; @@ -137,10 +138,14 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { .setSplitType(new ExpandContainersSplitType()) .build(); + private final WindowLayoutComponentImpl mWindowLayoutComponent; private final SplitController mController; - SplitPresenter(@NonNull Executor executor, @NonNull SplitController controller) { + SplitPresenter(@NonNull Executor executor, + @NonNull WindowLayoutComponentImpl windowLayoutComponent, + @NonNull SplitController controller) { super(executor, controller); + mWindowLayoutComponent = windowLayoutComponent; mController = controller; registerOrganizer(); if (!SplitController.ENABLE_SHELL_TRANSITIONS) { @@ -556,7 +561,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { return sanitizeSplitAttributes(taskProperties, defaultSplitAttributes, minDimensionsPair); } - final WindowLayoutInfo windowLayoutInfo = mController.mWindowLayoutComponent + final WindowLayoutInfo windowLayoutInfo = mWindowLayoutComponent .getCurrentWindowLayoutInfo(taskProperties.getDisplayId(), taskConfiguration.windowConfiguration); final SplitAttributesCalculatorParams params = new SplitAttributesCalculatorParams( @@ -838,7 +843,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final int displayId = taskProperties.getDisplayId(); final WindowConfiguration windowConfiguration = taskProperties.getConfiguration() .windowConfiguration; - final WindowLayoutInfo info = mController.mWindowLayoutComponent + final WindowLayoutInfo info = mWindowLayoutComponent .getCurrentWindowLayoutInfo(displayId, windowConfiguration); final List<DisplayFeature> displayFeatures = info.getDisplayFeatures(); if (displayFeatures.isEmpty()) { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index 84b2bfc38559..c9f870005eb9 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -35,6 +35,8 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.util.ArrayMap; +import android.view.WindowManager; +import android.window.TaskFragmentOrganizer; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; @@ -43,13 +45,13 @@ import androidx.annotation.UiContext; import androidx.window.common.CommonFoldingFeature; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.common.EmptyLifecycleCallbacksAdapter; -import androidx.window.common.RawFoldingFeatureProducer; import androidx.window.util.DataProducer; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Consumer; @@ -80,13 +82,16 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { private final Map<IBinder, ConfigurationChangeListener> mConfigurationChangeListeners = new ArrayMap<>(); - public WindowLayoutComponentImpl(@NonNull Context context) { + private final TaskFragmentOrganizer mTaskFragmentOrganizer; + + public WindowLayoutComponentImpl(@NonNull Context context, + @NonNull TaskFragmentOrganizer taskFragmentOrganizer, + @NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) { ((Application) context.getApplicationContext()) .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged()); - RawFoldingFeatureProducer foldingFeatureProducer = new RawFoldingFeatureProducer(context); - mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context, - foldingFeatureProducer); + mFoldingFeatureProducer = foldingFeatureProducer; mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged); + mTaskFragmentOrganizer = taskFragmentOrganizer; } /** Registers to listen to {@link CommonFoldingFeature} changes */ @@ -182,7 +187,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { @GuardedBy("mLock") private boolean isListeningForLayoutChanges(IBinder token) { - for (Context context: getContextsListeningForLayoutChanges()) { + for (Context context : getContextsListeningForLayoutChanges()) { if (token.equals(Context.getToken(context))) { return true; } @@ -230,8 +235,9 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { /** * Translates the {@link DisplayFeature} into a {@link WindowLayoutInfo} when a * valid state is found. + * * @param context a proxy for the {@link android.view.Window} that contains the - * {@link DisplayFeature}. + * {@link DisplayFeature}. */ private WindowLayoutInfo getWindowLayoutInfo(@NonNull @UiContext Context context, List<CommonFoldingFeature> storedFeatures) { @@ -243,7 +249,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { * Gets the current {@link WindowLayoutInfo} computed with passed {@link WindowConfiguration}. * * @return current {@link WindowLayoutInfo} on the default display. Returns - * empty {@link WindowLayoutInfo} on secondary displays. + * empty {@link WindowLayoutInfo} on secondary displays. */ @NonNull public WindowLayoutInfo getCurrentWindowLayoutInfo(int displayId, @@ -254,7 +260,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } } - /** @see #getWindowLayoutInfo(Context, List) */ + /** @see #getWindowLayoutInfo(Context, List) */ private WindowLayoutInfo getWindowLayoutInfo(int displayId, @NonNull WindowConfiguration windowConfiguration, List<CommonFoldingFeature> storedFeatures) { @@ -278,7 +284,8 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { * * @param context a proxy for the {@link android.view.Window} that contains the * {@link DisplayFeature}. - * are within the {@link android.view.Window} of the {@link Activity} + * @return a {@link List} of {@link DisplayFeature}s that are within the + * {@link android.view.Window} of the {@link Activity} */ private List<DisplayFeature> getDisplayFeatures( @NonNull @UiContext Context context, List<CommonFoldingFeature> storedFeatures) { @@ -317,8 +324,11 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } /** - * Checks whether display features should be reported for the activity. + * Calculates if the display features should be reported for the UI Context. The calculation + * uses the task information because that is accurate for Activities in ActivityEmbedding mode. * TODO(b/238948678): Support reporting display features in all windowing modes. + * + * @return true if the display features should be reported for the UI Context, false otherwise. */ private boolean shouldReportDisplayFeatures(@NonNull @UiContext Context context) { int displayId = context.getDisplay().getDisplayId(); @@ -337,7 +347,27 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { // bounds in this case can't be computed correctly, so we should skip. return false; } - windowingMode = taskConfig.windowConfiguration.getWindowingMode(); + final Rect taskBounds = taskConfig.windowConfiguration.getBounds(); + final WindowManager windowManager = Objects.requireNonNull( + context.getSystemService(WindowManager.class)); + final Rect currentBounds = windowManager.getCurrentWindowMetrics().getBounds(); + final Rect maxBounds = windowManager.getMaximumWindowMetrics().getBounds(); + boolean isTaskExpanded = maxBounds.equals(taskBounds); + boolean isActivityExpanded = maxBounds.equals(currentBounds); + /* + * We need to proxy being in full screen because when a user enters PiP and exits PiP + * the task windowingMode will report multi-window/pinned until the transition is + * finished in WM Shell. + * maxBounds == taskWindowBounds is a proxy check to verify the window is full screen + * For tasks that are letterboxed, we use currentBounds == maxBounds to filter these + * out. + */ + // TODO(b/262900133) remove currentBounds check when letterboxed apps report bounds. + // currently we don't want to report to letterboxed apps since they do not update the + // window bounds when the Activity is moved. An inaccurate fold will be reported so + // we skip. + return isTaskExpanded && (isActivityExpanded + || mTaskFragmentOrganizer.isActivityEmbedded(activityToken)); } else { // TODO(b/242674941): use task windowing mode for window context that associates with // activity. @@ -390,6 +420,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } @Override - public void onLowMemory() {} + public void onLowMemory() { + } } } diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java index 3cc31f9761c1..81c39571bffa 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java @@ -90,6 +90,7 @@ import android.window.WindowContainerTransaction; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.extensions.layout.WindowLayoutComponentImpl; import androidx.window.extensions.layout.WindowLayoutInfo; @@ -142,7 +143,9 @@ public class SplitControllerTest { MockitoAnnotations.initMocks(this); doReturn(new WindowLayoutInfo(new ArrayList<>())).when(mWindowLayoutComponent) .getCurrentWindowLayoutInfo(anyInt(), any()); - mSplitController = new SplitController(mWindowLayoutComponent); + DeviceStateManagerFoldingFeatureProducer producer = + mock(DeviceStateManagerFoldingFeatureProducer.class); + mSplitController = new SplitController(mWindowLayoutComponent, producer); mSplitPresenter = mSplitController.mPresenter; mSplitInfos = new ArrayList<>(); mEmbeddingCallback = splitInfos -> { diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java index fcd4d621e753..121e81394b2d 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java @@ -75,6 +75,7 @@ import android.window.WindowContainerTransaction; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.extensions.layout.WindowLayoutComponentImpl; import androidx.window.extensions.layout.WindowLayoutInfo; @@ -117,7 +118,9 @@ public class SplitPresenterTest { MockitoAnnotations.initMocks(this); doReturn(new WindowLayoutInfo(new ArrayList<>())).when(mWindowLayoutComponent) .getCurrentWindowLayoutInfo(anyInt(), any()); - mController = new SplitController(mWindowLayoutComponent); + DeviceStateManagerFoldingFeatureProducer producer = + mock(DeviceStateManagerFoldingFeatureProducer.class); + mController = new SplitController(mWindowLayoutComponent, producer); mPresenter = mController.mPresenter; spyOn(mController); spyOn(mPresenter); diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java index 98772360a321..7d9d8b0f3a06 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java @@ -45,6 +45,8 @@ import android.window.WindowContainerTransaction; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; +import androidx.window.extensions.layout.WindowLayoutComponentImpl; import com.google.android.collect.Lists; @@ -82,7 +84,10 @@ public class TaskFragmentContainerTest { @Before public void setup() { MockitoAnnotations.initMocks(this); - mController = new SplitController(); + DeviceStateManagerFoldingFeatureProducer producer = + mock(DeviceStateManagerFoldingFeatureProducer.class); + WindowLayoutComponentImpl component = mock(WindowLayoutComponentImpl.class); + mController = new SplitController(component, producer); spyOn(mController); mActivity = createMockActivity(); mIntent = new Intent(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java index 477bc955212b..95a89b1d23ff 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java @@ -224,16 +224,6 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, mObscuredTouchRegion = obscuredRegion; } - private void onLocationChanged(WindowContainerTransaction wct) { - // Update based on the screen bounds - getBoundsOnScreen(mTmpRect); - getRootView().getBoundsOnScreen(mTmpRootRect); - if (!mTmpRootRect.contains(mTmpRect)) { - mTmpRect.offsetTo(0, 0); - } - wct.setBounds(mTaskToken, mTmpRect); - } - /** * Call when view position or size has changed. Do not call when animating. */ @@ -246,10 +236,15 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, if (isUsingShellTransitions() && mTaskViewTransitions.hasPending()) return; WindowContainerTransaction wct = new WindowContainerTransaction(); - onLocationChanged(wct); + updateWindowBounds(wct); mSyncQueue.queue(wct); } + private void updateWindowBounds(WindowContainerTransaction wct) { + getBoundsOnScreen(mTmpRect); + wct.setBounds(mTaskToken, mTmpRect); + } + /** * Release this container if it is initialized. */ @@ -573,7 +568,7 @@ public class TaskView extends SurfaceView implements SurfaceHolder.Callback, .apply(); // TODO: determine if this is really necessary or not - onLocationChanged(wct); + updateWindowBounds(wct); } else { // The surface has already been destroyed before the task has appeared, // so go ahead and hide the task entirely diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java index 922472a26113..09dc68a4ccea 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java @@ -870,7 +870,8 @@ public class Bubble implements BubbleViewProvider { pw.print(" desiredHeight: "); pw.println(getDesiredHeightString()); pw.print(" suppressNotif: "); pw.println(shouldSuppressNotification()); pw.print(" autoExpand: "); pw.println(shouldAutoExpand()); - pw.print(" bubbleMetadataFlagListener null: " + (mBubbleMetadataFlagListener == null)); + pw.print(" isClearable: "); pw.println(mIsClearable); + pw.println(" bubbleMetadataFlagListener null: " + (mBubbleMetadataFlagListener == null)); if (mExpandedView != null) { mExpandedView.dump(pw); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java index 81eefe25704e..8196c5ab08e4 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java @@ -224,16 +224,18 @@ public class UnfoldAnimationControllerTest extends ShellTestCase { mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash); assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId); + mUnfoldAnimationController.onStateChangeStarted(); mUnfoldAnimationController.onTaskVanished(taskInfo); + mUnfoldAnimationController.onStateChangeFinished(); assertThat(mTaskAnimator1.mResetTasks).contains(taskInfo.taskId); } @Test - public void testApplicablePinnedTaskDisappeared_doesNotResetSurface() { - mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2); + public void testApplicableTaskDisappeared_noStateChange_doesNotResetSurface() { + mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 0); RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder() - .setWindowingMode(2).build(); + .setWindowingMode(0).build(); mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash); assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId); @@ -249,7 +251,9 @@ public class UnfoldAnimationControllerTest extends ShellTestCase { .setWindowingMode(0).build(); mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash); + mUnfoldAnimationController.onStateChangeStarted(); mUnfoldAnimationController.onTaskVanished(taskInfo); + mUnfoldAnimationController.onStateChangeFinished(); assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId); } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt index 5ac3aad749fc..67159512a701 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt @@ -49,13 +49,16 @@ data class TurbulenceNoiseAnimationConfig( val opacity: Int = DEFAULT_OPACITY, val width: Float = 0f, val height: Float = 0f, - val duration: Float = DEFAULT_NOISE_DURATION_IN_MILLIS, + val maxDuration: Float = DEFAULT_MAX_DURATION_IN_MILLIS, + val easeInDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS, + val easeOutDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS, val pixelDensity: Float = 1f, val blendMode: BlendMode = DEFAULT_BLEND_MODE, val onAnimationEnd: Runnable? = null ) { companion object { - const val DEFAULT_NOISE_DURATION_IN_MILLIS = 7500F + const val DEFAULT_MAX_DURATION_IN_MILLIS = 7500f + const val DEFAULT_EASING_DURATION_IN_MILLIS = 750f const val DEFAULT_LUMINOSITY_MULTIPLIER = 1f const val DEFAULT_NOISE_GRID_COUNT = 1.2f const val DEFAULT_NOISE_SPEED_Z = 0.3f diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt index 4c7e5f4c7093..b8f4b276dd6a 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt @@ -15,16 +15,106 @@ */ package com.android.systemui.surfaceeffects.turbulencenoise -/** A controller that plays [TurbulenceNoiseView]. */ +import android.view.View +import androidx.annotation.VisibleForTesting +import java.util.Random + +/** Plays [TurbulenceNoiseView] in ease-in, main (no easing), and ease-out order. */ class TurbulenceNoiseController(private val turbulenceNoiseView: TurbulenceNoiseView) { + + companion object { + /** + * States of the turbulence noise animation. + * + * <p>The state is designed to be follow the order below: [AnimationState.EASE_IN], + * [AnimationState.MAIN], [AnimationState.EASE_OUT]. + */ + enum class AnimationState { + EASE_IN, + MAIN, + EASE_OUT, + NOT_PLAYING + } + } + + private val random = Random() + + /** Current state of the animation. */ + @VisibleForTesting + var state: AnimationState = AnimationState.NOT_PLAYING + set(value) { + field = value + if (state == AnimationState.NOT_PLAYING) { + turbulenceNoiseView.visibility = View.INVISIBLE + turbulenceNoiseView.clearConfig() + } else { + turbulenceNoiseView.visibility = View.VISIBLE + } + } + + init { + turbulenceNoiseView.visibility = View.INVISIBLE + } + /** Updates the color of the noise. */ fun updateNoiseColor(color: Int) { + if (state == AnimationState.NOT_PLAYING) { + return + } turbulenceNoiseView.updateColor(color) } - // TODO: add cancel and/ or pause once design requirements become clear. - /** Plays [TurbulenceNoiseView] with the given config. */ - fun play(turbulenceNoiseAnimationConfig: TurbulenceNoiseAnimationConfig) { - turbulenceNoiseView.play(turbulenceNoiseAnimationConfig) + /** + * Plays [TurbulenceNoiseView] with the given config. + * + * <p>It plays ease-in, main, and ease-out animations in sequence. + */ + fun play(config: TurbulenceNoiseAnimationConfig) { + if (state != AnimationState.NOT_PLAYING) { + return // Ignore if any of the animation is playing. + } + + turbulenceNoiseView.applyConfig(config) + playEaseInAnimation() + } + + // TODO(b/237282226): Support force finish. + /** Finishes the main animation, which triggers the ease-out animation. */ + fun finish() { + if (state == AnimationState.MAIN) { + turbulenceNoiseView.finish(nextAnimation = this::playEaseOutAnimation) + } + } + + private fun playEaseInAnimation() { + if (state != AnimationState.NOT_PLAYING) { + return + } + state = AnimationState.EASE_IN + + // Add offset to avoid repetitive noise. + turbulenceNoiseView.playEaseIn( + offsetX = random.nextFloat(), + offsetY = random.nextFloat(), + this::playMainAnimation + ) + } + + private fun playMainAnimation() { + if (state != AnimationState.EASE_IN) { + return + } + state = AnimationState.MAIN + + turbulenceNoiseView.play(this::playEaseOutAnimation) + } + + private fun playEaseOutAnimation() { + if (state != AnimationState.MAIN) { + return + } + state = AnimationState.EASE_OUT + + turbulenceNoiseView.playEaseOut(onAnimationEnd = { state = AnimationState.NOT_PLAYING }) } } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt index 19c114d2693c..7456c4334f0f 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt @@ -114,8 +114,19 @@ class TurbulenceNoiseShader : RuntimeShader(TURBULENCE_NOISE_SHADER) { setFloatUniform("in_aspectRatio", width / max(height, 0.001f)) } - /** Sets noise move speed in x, y, and z direction. */ + /** Current noise movements in x, y, and z axes. */ + var noiseOffsetX: Float = 0f + private set + var noiseOffsetY: Float = 0f + private set + var noiseOffsetZ: Float = 0f + private set + + /** Sets noise move offset in x, y, and z direction. */ fun setNoiseMove(x: Float, y: Float, z: Float) { - setFloatUniform("in_noiseMove", x, y, z) + noiseOffsetX = x + noiseOffsetY = y + noiseOffsetZ = z + setFloatUniform("in_noiseMove", noiseOffsetX, noiseOffsetY, noiseOffsetZ) } } diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt index 68712c6cd1de..e1e515d14771 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt @@ -25,75 +25,162 @@ import android.util.AttributeSet import android.view.View import androidx.annotation.VisibleForTesting import androidx.core.graphics.ColorUtils -import java.util.Random -import kotlin.math.sin -/** View that renders turbulence noise effect. */ +/** + * View that renders turbulence noise effect. + * + * <p>Use [TurbulenceNoiseController] to control the turbulence animation. If you want to make some + * other turbulence noise effects, either add functionality to [TurbulenceNoiseController] or create + * another controller instead of extend or modify the [TurbulenceNoiseView]. + * + * <p>Please keep the [TurbulenceNoiseView] (or View in general) not aware of the state. + * + * <p>Please avoid inheriting the View if possible. Instead, reconsider adding a controller for a + * new case. + */ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { companion object { private const val MS_TO_SEC = 0.001f - private const val TWO_PI = Math.PI.toFloat() * 2f } - @VisibleForTesting val turbulenceNoiseShader = TurbulenceNoiseShader() + private val turbulenceNoiseShader = TurbulenceNoiseShader() private val paint = Paint().apply { this.shader = turbulenceNoiseShader } - private val random = Random() - private val animator: ValueAnimator = ValueAnimator.ofFloat(0f, 1f) - private var config: TurbulenceNoiseAnimationConfig? = null + @VisibleForTesting var noiseConfig: TurbulenceNoiseAnimationConfig? = null + @VisibleForTesting var currentAnimator: ValueAnimator? = null - val isPlaying: Boolean - get() = animator.isRunning + override fun onDraw(canvas: Canvas?) { + if (canvas == null || !canvas.isHardwareAccelerated) { + // Drawing with the turbulence noise shader requires hardware acceleration, so skip + // if it's unsupported. + return + } - init { - // Only visible during the animation. - visibility = INVISIBLE + canvas.drawPaint(paint) } /** Updates the color during the animation. No-op if there's no animation playing. */ - fun updateColor(color: Int) { - config?.let { - it.color = color - applyConfig(it) + internal fun updateColor(color: Int) { + noiseConfig?.let { + turbulenceNoiseShader.setColor(ColorUtils.setAlphaComponent(color, it.opacity)) } } - override fun onDraw(canvas: Canvas?) { - if (canvas == null || !canvas.isHardwareAccelerated) { - // Drawing with the turbulence noise shader requires hardware acceleration, so skip - // if it's unsupported. + /** Plays the turbulence noise with no easing. */ + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + fun play(onAnimationEnd: Runnable? = null) { + if (noiseConfig == null) { return } + val config = noiseConfig!! - canvas.drawPaint(paint) + val animator = ValueAnimator.ofFloat(0f, 1f) + animator.duration = config.maxDuration.toLong() + + // Animation should start from the initial position to avoid abrupt transition. + val initialX = turbulenceNoiseShader.noiseOffsetX + val initialY = turbulenceNoiseShader.noiseOffsetY + val initialZ = turbulenceNoiseShader.noiseOffsetZ + + animator.addUpdateListener { updateListener -> + val timeInSec = updateListener.currentPlayTime * MS_TO_SEC + turbulenceNoiseShader.setNoiseMove( + initialX + timeInSec * config.noiseMoveSpeedX, + initialY + timeInSec * config.noiseMoveSpeedY, + initialZ + timeInSec * config.noiseMoveSpeedZ + ) + + turbulenceNoiseShader.setOpacity(config.luminosityMultiplier) + + invalidate() + } + + animator.addListener( + object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + currentAnimator = null + onAnimationEnd?.run() + } + } + ) + + animator.start() + currentAnimator = animator + } + + /** Plays the turbulence noise with linear ease-in. */ + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + fun playEaseIn(offsetX: Float = 0f, offsetY: Float = 0f, onAnimationEnd: Runnable? = null) { + if (noiseConfig == null) { + return + } + val config = noiseConfig!! + + val animator = ValueAnimator.ofFloat(0f, 1f) + animator.duration = config.easeInDuration.toLong() + + // Animation should start from the initial position to avoid abrupt transition. + val initialX = turbulenceNoiseShader.noiseOffsetX + val initialY = turbulenceNoiseShader.noiseOffsetY + val initialZ = turbulenceNoiseShader.noiseOffsetZ + + animator.addUpdateListener { updateListener -> + val timeInSec = updateListener.currentPlayTime * MS_TO_SEC + val progress = updateListener.animatedValue as Float + + turbulenceNoiseShader.setNoiseMove( + offsetX + initialX + timeInSec * config.noiseMoveSpeedX, + offsetY + initialY + timeInSec * config.noiseMoveSpeedY, + initialZ + timeInSec * config.noiseMoveSpeedZ + ) + + // TODO: Replace it with a better curve. + turbulenceNoiseShader.setOpacity(progress * config.luminosityMultiplier) + + invalidate() + } + + animator.addListener( + object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator) { + currentAnimator = null + onAnimationEnd?.run() + } + } + ) + + animator.start() + currentAnimator = animator } - fun play(config: TurbulenceNoiseAnimationConfig) { - if (isPlaying) { - return // Ignore if the animation is playing. + /** Plays the turbulence noise with linear ease-out. */ + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + fun playEaseOut(onAnimationEnd: Runnable? = null) { + if (noiseConfig == null) { + return } - visibility = VISIBLE - applyConfig(config) + val config = noiseConfig!! + + val animator = ValueAnimator.ofFloat(0f, 1f) + animator.duration = config.easeOutDuration.toLong() - // Add random offset to avoid same patterned noise. - val offsetX = random.nextFloat() - val offsetY = random.nextFloat() + // Animation should start from the initial position to avoid abrupt transition. + val initialX = turbulenceNoiseShader.noiseOffsetX + val initialY = turbulenceNoiseShader.noiseOffsetY + val initialZ = turbulenceNoiseShader.noiseOffsetZ - animator.duration = config.duration.toLong() animator.addUpdateListener { updateListener -> val timeInSec = updateListener.currentPlayTime * MS_TO_SEC - // Remap [0,1] to [0, 2*PI] - val progress = TWO_PI * updateListener.animatedValue as Float + val progress = updateListener.animatedValue as Float turbulenceNoiseShader.setNoiseMove( - offsetX + timeInSec * config.noiseMoveSpeedX, - offsetY + timeInSec * config.noiseMoveSpeedY, - timeInSec * config.noiseMoveSpeedZ + initialX + timeInSec * config.noiseMoveSpeedX, + initialY + timeInSec * config.noiseMoveSpeedY, + initialZ + timeInSec * config.noiseMoveSpeedZ ) - // Fade in and out the noise as the animation progress. - // TODO: replace it with a better curve - turbulenceNoiseShader.setOpacity(sin(TWO_PI - progress) * config.luminosityMultiplier) + // TODO: Replace it with a better curve. + turbulenceNoiseShader.setOpacity((1f - progress) * config.luminosityMultiplier) invalidate() } @@ -101,16 +188,31 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex animator.addListener( object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - visibility = INVISIBLE - config.onAnimationEnd?.run() + currentAnimator = null + onAnimationEnd?.run() } } ) + animator.start() + currentAnimator = animator + } + + /** Finishes the current animation if playing and plays the next animation if given. */ + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + fun finish(nextAnimation: Runnable? = null) { + // Calling Animator#end sets the animation state back to the initial state. Using pause to + // avoid visual artifacts. + currentAnimator?.pause() + currentAnimator = null + + nextAnimation?.run() } - private fun applyConfig(config: TurbulenceNoiseAnimationConfig) { - this.config = config + /** Applies shader uniforms. Must be called before playing animation. */ + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + fun applyConfig(config: TurbulenceNoiseAnimationConfig) { + noiseConfig = config with(turbulenceNoiseShader) { setGridCount(config.gridCount) setColor(ColorUtils.setAlphaComponent(config.color, config.opacity)) @@ -120,4 +222,8 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex } paint.blendMode = config.blendMode } + + internal fun clearConfig() { + noiseConfig = null + } } diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java index eac765ab45b2..51f5baa8b45f 100644 --- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java +++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java @@ -40,6 +40,11 @@ import java.util.List; */ @ProvidesInterface(action = BcSmartspaceDataPlugin.ACTION, version = BcSmartspaceDataPlugin.VERSION) public interface BcSmartspaceDataPlugin extends Plugin { + String UI_SURFACE_LOCK_SCREEN_AOD = "lockscreen"; + String UI_SURFACE_HOME_SCREEN = "home"; + String UI_SURFACE_MEDIA = "media_data_manager"; + String UI_SURFACE_DREAM = "dream"; + String ACTION = "com.android.systemui.action.PLUGIN_BC_SMARTSPACE_DATA"; int VERSION = 1; String TAG = "BcSmartspaceDataPlugin"; @@ -100,6 +105,11 @@ public interface BcSmartspaceDataPlugin extends Plugin { void setIsDreaming(boolean isDreaming); /** + * Set the UI surface for the cards. Should be called immediately after the view is created. + */ + void setUiSurface(String uiSurface); + + /** * Range [0.0 - 1.0] when transitioning from Lockscreen to/from AOD */ void setDozeAmount(float amount); diff --git a/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml b/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml index b3987f1aeeda..951d6fed0a17 100644 --- a/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml +++ b/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml @@ -99,4 +99,9 @@ android:fromId="@id/unlocked" android:toId="@id/locked_aod" android:drawable="@drawable/unlocked_to_aod_lock" /> + + <transition + android:fromId="@id/unlocked" + android:toId="@id/locked" + android:drawable="@drawable/unlocked_to_locked" /> </animated-selector> diff --git a/packages/SystemUI/res-keyguard/drawable/unlocked_to_locked.xml b/packages/SystemUI/res-keyguard/drawable/unlocked_to_locked.xml new file mode 100644 index 000000000000..b55abd1fdddc --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable/unlocked_to_locked.xml @@ -0,0 +1,145 @@ +<?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. +--> +<animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android"> + <aapt:attr name="android:drawable"> + <vector android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46"> + <group android:name="_R_G"> + <group android:name="_R_G_L_2_G_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02"> + <group android:name="_R_G_L_2_G" android:translateX="-8.75" android:translateY="-8.75"> + <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#FF000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " /> + </group> + </group> + <group android:name="_R_G_L_1_G_N_4_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02"> + <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="-8.75" android:translateY="-8.75"> + <group android:name="_R_G_L_1_G" android:translateX="8.995" android:translateY="18.431" android:scaleX="0.98039" android:scaleY="0.98039"> + <path android:name="_R_G_L_1_G_D_0_P_0" android:strokeColor="#FF000000" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M11.25 -0.64 C11.25,-0.64 11.25,13.64 11.25,13.64 C11.25,15.22 9.97,16.5 8.39,16.5 C8.39,16.5 -8.39,16.5 -8.39,16.5 C-9.97,16.5 -11.25,15.22 -11.25,13.64 C-11.25,13.64 -11.25,-0.64 -11.25,-0.64 C-11.25,-2.22 -9.97,-3.5 -8.39,-3.5 C-8.39,-3.5 8.39,-3.5 8.39,-3.5 C9.97,-3.5 11.25,-2.22 11.25,-0.64c " /> + </group> + </group> + </group> + <group android:name="_R_G_L_0_G_N_4_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02"> + <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="-8.75" android:translateY="-8.75"> + <group android:name="_R_G_L_0_G" android:translateX="8.995000000000001" android:translateY="18.345000000000002" android:pivotX="-0.031" android:pivotY="4.406" android:scaleX="0.98039" android:scaleY="0.98039"> + <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#FF000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-0.09 8.63 C1.2,8.63 2.25,7.57 2.25,6.28 C2.25,4.99 1.2,3.94 -0.09,3.94 C-1.39,3.94 -2.44,4.99 -2.44,6.28 C-2.44,7.57 -1.39,8.63 -0.09,8.63c " /> + </group> + </group> + </group> + </group> + <group android:name="time_group" /> + </vector> + </aapt:attr> + <target android:name="_R_G_L_2_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="strokeWidth" android:duration="333" android:startOffset="0" android:valueFrom="2" android:valueTo="2" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0.833,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_2_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="pathData" android:duration="83" android:startOffset="0" android:valueFrom="M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " android:valueTo="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.456,0 0.464,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="pathData" android:duration="133" android:startOffset="83" android:valueFrom="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueTo="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.606,0 0.035,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="pathData" android:duration="117" android:startOffset="217" android:valueFrom="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueTo="M2.52 14.65 C2.52,14.65 2.5,8.61 2.5,8.61 C2.5,5.24 5.3,2.5 8.75,2.5 C12.2,2.5 15,5.24 15,8.61 C15,8.61 15.02,14.65 15.02,14.65 " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.511,0 0.409,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_2_G_T_1"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_1_G_N_4_T_1"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_N_4_T_1"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="22.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="translateY" android:duration="67" android:startOffset="333" android:valueFrom="22.25" android:valueTo="24.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.535,0 0.426,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="translateY" android:duration="100" android:startOffset="400" android:valueFrom="24.25" android:valueTo="22.25" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.641,0 0.499,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateX" android:duration="850" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" /> + </set> + </aapt:attr> + </target> +</animated-vector> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 35d0981b96e0..c0509a9f7702 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Beweeg nader aan <xliff:g id="DEVICENAME">%1$s</xliff:g> om hier te speel"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Speel tans op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Iets is fout. Probeer weer."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrole is nie beskikbaar nie"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index cfb8ad0a8040..d0c5c9040ea8 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"እዚህ ለመጫወት ወደ <xliff:g id="DEVICENAME">%1$s</xliff:g> ቀረብ ይበሉ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ በማጫወት ላይ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"የሆነ ችግር ተፈጥሯል። እንደገና ይሞክሩ።"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"አልተገኘም"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"መቆጣጠሪያ አይገኝም"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 7568eb7942c5..ea5bce12b3db 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"يُرجى الاقتراب من <xliff:g id="DEVICENAME">%1$s</xliff:g> لتشغيل الوسائط هنا."</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"جارٍ تشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"حدث خطأ. يُرجى إعادة المحاولة."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string> <string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"عنصر التحكّم غير متوفّر"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• تثبيت تطبيق كاميرا"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• إعداد التطبيق"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• توفُّر جهاز واحد على الأقل"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"انقر مع الاستمرار على الاختصار."</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"إلغاء"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"قلب الجهاز الآن"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"عليك فتح الهاتف لالتقاط صورة ذاتية بشكل أفضل."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index def260793ad6..cbd2bedd3f20 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ইয়াত খেলিবলৈ <xliff:g id="DEVICENAME">%1$s</xliff:g>ৰ আৰু ওচৰলৈ যাওক"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে কৰি থকা হৈছে"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্টো পৰীক্ষা কৰক"</string> <string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"নিয়ন্ত্ৰণটো উপলব্ধ নহয়"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index c3378dde36fb..dd4d5109855d 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oxutmaq üçün <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaxınlaşın"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxudulur"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Xəta oldu. Yenə cəhd edin."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Nəzarət əlçatan deyil"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 2b50c3631019..64313896a4ce 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu puštali"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Pušta se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 7394df3bef5b..7e7262a057d3 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Падыдзіце бліжэй да прылады \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", каб прайграць на гэтай"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Прайграецца на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Нешта пайшло не так. Паўтарыце спробу."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Кіраванне недаступнае"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Усталявана праграма \"Камера\"."</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Праграма наладжана."</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Даступная хаця б адна прылада."</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Дакраніцеся і ўтрымлівайце ярлык"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасаваць"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Пераключыць"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Каб атрымаць лепшае сэлфі, раскрыйце тэлефон"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 44e4e95dda17..26a154fadc56 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за възпроизвеждане на това устройство"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Възпроизвежда се на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Нещо се обърка. Опитайте отново."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е налице"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 384b18308468..b6069a4a9361 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"এখান থেকে চালাতে <xliff:g id="DEVICENAME">%1$s</xliff:g>-এর কাছে নিয়ে যান"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ ভিডিও চালানো হচ্ছে"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"কোনও সমস্যা হয়েছে। আবার চেষ্টা করুন।"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string> <string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"কন্ট্রোল উপলভ্য নেই"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index d6217722287b..1ab7594ca0fb 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da na njemu reproducirate"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije uredu. Pokušajte ponovo."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 4b77f089b5e0..2f48676a142a 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acosta\'t a <xliff:g id="DEVICENAME">%1$s</xliff:g> per reproduir el contingut aquí"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"S\'està reproduint a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"S\'ha produït un error. Torna-ho a provar."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no està disponible"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 48f6dfe53d14..feeaa32f68a7 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pokud zde chcete přehrávat média, přibližte se k zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Přehrávání v zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo k chybě. Zkuste to znovu."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nenalezeno"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládání není k dispozici"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index aa0f20c0b899..f64587e26731 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ryk tættere på <xliff:g id="DEVICENAME">%1$s</xliff:g> for at afspille her"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspilles på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Noget gik galt. Prøv igen."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Styringselement ikke tilgængeligt"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index f94c192ec1b0..bd4c5872dfce 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Platziere für die Wiedergabe dein Gerät näher an „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Wird auf „<xliff:g id="DEVICENAME">%1$s</xliff:g>“ abgespielt"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Es gab ein Problem. Versuch es noch einmal."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Steuerelement nicht verfügbar"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index ea2f0c97fffa..05cf06cc4ba0 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Μετακινηθείτε πιο κοντά στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g> για αναπαραγωγή εδώ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε ξανά."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Δεν βρέθηκε."</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Μη διαθέσιμο στοιχείο ελέγχου"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index faaefe05b7d9..2c960c62478c 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 7f703df7ec89..d09f71f944d1 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index faaefe05b7d9..2c960c62478c 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index faaefe05b7d9..2c960c62478c 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index e21550f3d140..7b0837d1a77a 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g> to play here"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Playing on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index def72e897a59..55303e8b8f2e 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproducir aquí"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Se produjo un error. Vuelve a intentarlo."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 5146e74bc1fa..c2443daccceb 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para jugar aquí"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string> <string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Control no disponible"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 7b2bd3e197c4..b31030a42fe3 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siin esitamiseks liigutage seadmele <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemale"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Esitatakse seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Midagi läks valesti. Proovige uuesti."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Juhtelement pole saadaval"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 3fb9726be8e4..de9c75f45af8 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Gerturatu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailura bertan erreproduzitzen ari dena hemen erreproduzitzeko"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzen"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Arazoren bat izan da. Saiatu berriro."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Ez dago erabilgarri kontrolatzeko aukera"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 161117a423c6..87aed942d05e 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"برای پخش در اینجا، به <xliff:g id="DEVICENAME">%1$s</xliff:g> نزدیکتر شوید"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"درحال پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"مشکلی پیش آمد. دوباره امتحان کنید."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string> <string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"کنترل دردسترس نیست"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 33108eb8445c..f7bb7f701687 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -724,7 +724,7 @@ <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> on käynnissä"</string> <string name="instant_apps_message" msgid="6112428971833011754">"Sovellus avattiin ilman asennusta."</string> <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Sovellus avattiin ilman asennusta. Katso lisätietoja napauttamalla."</string> - <string name="app_info" msgid="5153758994129963243">"Sovelluksen tiedot"</string> + <string name="app_info" msgid="5153758994129963243">"Sovellustiedot"</string> <string name="go_to_web" msgid="636673528981366511">"Siirry selaimeen"</string> <string name="mobile_data" msgid="4564407557775397216">"Mobiilidata"</string> <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string> @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Siirrä <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemmäs toistaaksesi täällä"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Toistetaan: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Jotain meni pieleen. Yritä uudelleen."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ei löydy"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Ohjain ei ole käytettävissä"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 184b907963e8..be81a9275544 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g> pour lire le contenu"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 9823ad016c7c..869166321079 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Rapprochez l\'appareil pour transférer la diffusion à votre <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lecture sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Commande indisponible"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index b27bd12cd48f..f9738e3b413a 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Achégate ao dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>) para reproducir o contido neste"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducindo contido noutro dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Produciuse un erro. Téntao de novo."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"O control non está dispoñible"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index e00f8d88be38..dac1403f8dd5 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"આમાં ચલાવવા માટે ડિવાઇસને <xliff:g id="DEVICENAME">%1$s</xliff:g>ની નજીક ખસેડો"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવામાં આવી રહ્યું છે"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string> <string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"નિયંત્રણ ઉપલબ્ધ નથી"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 49fb626ab6a6..38d2bffa239a 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"अपने डिवाइस पर मीडिया फ़ाइल ट्रांसफ़र करने के लिए, उसे <xliff:g id="DEVICENAME">%1$s</xliff:g> के पास ले जाएं"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चल रहा है"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"कोई गड़बड़ी हुई. फिर से कोशिश करें."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string> <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"कंट्रोल मौजूद नहीं है"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index e5253bc13a1f..7613317734d1 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g> da biste na njemu reproducirali"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproducira se na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije u redu. Pokušajte ponovo."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 6263126eb692..c2b94c0b1102 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Menjen közelebb a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközhöz, hogy itt játszhassa le a tartalmat"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Lejátszás folyamatban a(z) <xliff:g id="DEVICENAME">%1$s</xliff:g> eszközön"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Hiba történt. Próbálkozzon újra."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nem található"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Nem hozzáférhető vezérlő"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index f84530f41579..5623ecfb7f29 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ավելի մոտեցեք «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքին՝ նվագարկումը սկսելու համար"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Նվագարկվում է «<xliff:g id="DEVICENAME">%1$s</xliff:g>» սարքում"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Սխալ առաջացավ։ Նորից փորձեք։"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Չի գտնվել"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Կառավարման տարրը հասանելի չէ"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 2702f9281463..bf5f8b01848c 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan ke <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk memutar di sini"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Diputar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Terjadi error. Coba lagi."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol tidak tersedia"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 64c76773fa52..f3efb8624333 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Færðu tækið nær <xliff:g id="DEVICENAME">%1$s</xliff:g> til að spila hér"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Í spilun í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Eitthvað fór úrskeiðis. Reyndu aftur."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Stýring er ekki tiltæk"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 89817d19a8fc..e8c6a5b21308 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Avvicinati a <xliff:g id="DEVICENAME">%1$s</xliff:g> per riprodurre i contenuti qui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"In riproduzione su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Si è verificato un errore. Riprova."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Controllo non trovato"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Il controllo non è disponibile"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index ad9ccf13f6fd..690b6b22710c 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"צריך להתקרב אל <xliff:g id="DEVICENAME">%1$s</xliff:g> כדי להפעיל כאן"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"פועלת ב-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"משהו השתבש. יש לנסות שוב."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string> <string name="controls_error_removed" msgid="6675638069846014366">"לא נמצא"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"הפקד לא זמין"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 112db0530716..5bd580ccc603 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ここで再生するには<xliff:g id="DEVICENAME">%1$s</xliff:g>に近づいてください"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生しています"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"エラーが発生しました。もう一度お試しください。"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string> <string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"コントロールを使用できません"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 22e8a481e6f8..d25daf440ce2 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"მიუახლოვდით <xliff:g id="DEVICENAME">%1$s</xliff:g>-ს მისი მეშვეობით დასაკრავად"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"მიმდინარეობს დაკვრა <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"რაღაც შეცდომა მოხდა. ცადეთ ხელახლა."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ვერ მოიძებნა"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"კონტროლი მიუწვდომელია"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index d9ce21674ea7..bb24d6af3c0a 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Осы жерде ойнау үшін <xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысына жақындаңыз"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында ойнатылуда."</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Бірдеңе дұрыс болмады. Қайталап көріңіз."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару виджеті қолжетімсіз"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 830f2f24bab2..65953058322d 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"រំកិលឱ្យកាន់តែជិត <xliff:g id="DEVICENAME">%1$s</xliff:g> ដើម្បីចាក់នៅទីនេះ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"កំពុងចាក់នៅលើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើលកម្មវិធី"</string> <string name="controls_error_removed" msgid="6675638069846014366">"រកមិនឃើញទេ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"មិនអាចគ្រប់គ្រងបានទេ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index b142a10c1dfc..81a37f31aa8f 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು <xliff:g id="DEVICENAME">%1$s</xliff:g> ಸಮೀಪಕ್ಕೆ ಹೋಗಿ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ಏನೋ ತಪ್ಪಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ನಿಯಂತ್ರಣ ಲಭ್ಯವಿಲ್ಲ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index f9049f9fa05d..1570a6aa2370 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"현재 기기에서 재생하려면 <xliff:g id="DEVICENAME">%1$s</xliff:g>에 더 가까이 이동합니다."</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생 중"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"문제가 발생했습니다. 다시 시도해 주세요."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string> <string name="controls_error_removed" msgid="6675638069846014366">"찾을 수 없음"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"컨트롤을 사용할 수 없음"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index d579fc2d8c60..b1206840b722 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Бул жерде ойнотуу үчүн <xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүнө жакындатыңыз"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> аркылуу ойнотулууда"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Бир жерден ката кетти. Кайра аракет кылыңыз."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Табылган жок"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Башкара албайсыз"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 628d75e975d3..446deb05cf00 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ກະລຸນາຍ້າຍເຂົ້າໃກ້ <xliff:g id="DEVICENAME">%1$s</xliff:g> ເພື່ອຫຼິ້ນຢູ່ບ່ອນນີ້"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"ກຳລັງຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ. ກະລຸນາລອງໃໝ່."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ບໍ່ພົບ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ບໍ່ສາມາດໃຊ້ການຄວບຄຸມໄດ້"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 73a645ef4864..db518c100a0d 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Perkelkite arčiau „<xliff:g id="DEVICENAME">%1$s</xliff:g>“, kad būtų galima leisti čia"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Leidžiama įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Kažkas ne taip. Bandykite dar kartą."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nerasta"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Valdiklis nepasiekiamas"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 051779cafadc..5ea8da2889d8 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Pārvietojieties tuvāk ierīcei “<xliff:g id="DEVICENAME">%1$s</xliff:g>”, lai atskaņotu šeit"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Notiek atskaņošana ierīcē <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Radās kļūda. Mēģiniet vēlreiz."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Vadīkla nav pieejama"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Ir instalēta kameras lietotne."</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Lietotne ir iestatīta."</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ir pieejama vismaz viena ierīce."</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pieskarieties saīsnei un turiet."</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atcelt"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Apvērst tūlīt"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Labākas pašbildes uzņemšana, atlokot tālruni"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 02bfd4f0becb..0575b102e405 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g> за да пуштите тука"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пуштено на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Нешто не е во ред. Обидете се повторно."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 064927a8bc35..9a2353c6b8ad 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ഇവിടെ പ്ലേ ചെയ്യാൻ <xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിന് അടുത്തേക്ക് നീക്കുക"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യുന്നു"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"എന്തോ കുഴപ്പമുണ്ടായി. വീണ്ടും ശ്രമിക്കുക."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"കണ്ടെത്തിയില്ല"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"നിയന്ത്രണം ലഭ്യമല്ല"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 0c36e1df1cf4..08c47b0f4df4 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Энд тоглуулахын тулд <xliff:g id="DEVICENAME">%1$s</xliff:g>-д ойртоно уу"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулж байна"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Алдаа гарлаа. Дахин оролдоно уу."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Хяналт боломжгүй байна"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 93978c08f412..103e8d204772 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"येथे प्ले करण्यासाठी <xliff:g id="DEVICENAME">%1$s</xliff:g> च्या जवळ जा"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले केला जात आहे"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string> <string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"नियंत्रण उपलब्ध नाही"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• कॅमेरा अॅप इंस्टॉल करणे"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• अॅप सेट करणे"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• किमान एक डिव्हाइस उपलब्ध करणे"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"स्पर्श करा आणि धरून ठेवा शॉर्टकट"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करा"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"आता फ्लिप करा"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"आणखी चांगल्या सेल्फीसाठी फोनबद्दल अधिक जाणून घ्या"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 46aa1cb85bdb..b0b40962123f 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Dekatkan dengan <xliff:g id="DEVICENAME">%1$s</xliff:g> untuk bermain di sini"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Dimainkan pada <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Kesilapan telah berlaku. Cuba lagi."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kawalan tidak tersedia"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index edfe2e9fd9e5..2014f5c566c5 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ဤနေရာတွင်ဖွင့်ရန် <xliff:g id="DEVICENAME">%1$s</xliff:g> အနီးသို့တိုးပါ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင် ဖွင့်နေသည်"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"တစ်ခုခုမှားသွားသည်။ ထပ်စမ်းကြည့်ပါ။"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"မတွေ့ပါ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ထိန်းချုပ်မှု မရနိုင်ပါ"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index eb448aaf2c4d..2b1ebfdb4f27 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytt deg nærmere <xliff:g id="DEVICENAME">%1$s</xliff:g> for å spille av her"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spilles av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Noe gikk galt. Prøv på nytt."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrollen er utilgjengelig"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index f3db004b264b..3872b0dc26cc 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"तपाईं यहाँ प्ले गर्न चाहनुहुन्छ भने आफ्नो डिभाइसलाई <xliff:g id="DEVICENAME">%1$s</xliff:g> नजिकै लैजानुहोस्"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गरिँदै छ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"केही चिज गडबड भयो। फेरि प्रयास गर्नुहोस्।"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string> <string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"नियन्त्रण उपलब्ध छैन"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index da60323ab03a..e49b9fac5ccb 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ga dichter bij <xliff:g id="DEVICENAME">%1$s</xliff:g> staan om hier af te spelen"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Afspelen op <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Er is iets misgegaan. Probeer het opnieuw."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Niet gevonden"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Beheeroptie niet beschikbaar"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 8391e249772e..71d0822d078b 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ଏଠାରେ ଚଲାଇବା ପାଇଁ <xliff:g id="DEVICENAME">%1$s</xliff:g>ର ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ଚାଲୁଛି"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ନିୟନ୍ତ୍ରଣ ଉପଲବ୍ଧ ନାହିଁ"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• ଏକ କେମେରା ଆପ ଇନଷ୍ଟଲ କରିବା"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• ଆପ ସେଟ ଅପ କରାଯାଇଛି"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ଅତିକମରେ ଗୋଟିଏ ଡିଭାଇସ ଉପଲବ୍ଧ ଅଛି"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ସର୍ଟକଟକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ବାତିଲ କରନ୍ତୁ"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ବର୍ତ୍ତମାନ ଫ୍ଲିପ କରନ୍ତୁ"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"ଏକ ଉନ୍ନତ ସେଲ୍ଫି ପାଇଁ ଫୋନକୁ ଅନଫୋଲ୍ଡ କରନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 2a35dfcd8708..f6ad3ad01bac 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ਇੱਥੇ ਚਲਾਉਣ ਲਈ <xliff:g id="DEVICENAME">%1$s</xliff:g> ਦੇ ਨੇੜੇ ਜਾਓ"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 0bc0356e5dbc..7cced9e01ba2 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Zbliż do urządzenia <xliff:g id="DEVICENAME">%1$s</xliff:g>, aby na nim odtwarzać"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Odtwarzam na ekranie <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Coś poszło nie tak. Spróbuj ponownie."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Element jest niedostępny"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index a51ecccd2c21..41925480b3ad 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 27786bcb396f..ad93343fd081 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproduzir aqui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"A reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Algo correu mal. Tente novamente."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado."</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"O controlo está indisponível"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index a51ecccd2c21..41925480b3ad 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g> para abrir a mídia aqui"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Mídia aberta no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 318b6cff609f..e4a1b0bcf2e0 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Apropie-te de <xliff:g id="DEVICENAME">%1$s</xliff:g> ca să redai acolo"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Se redă pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"A apărut o eroare. Încearcă din nou."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verifică aplicația"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Comanda este indisponibilă"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 9da9c6d21fae..9b4975e712e6 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Для воспроизведения на этом устройстве подойдите ближе к другому (<xliff:g id="DEVICENAME">%1$s</xliff:g>)."</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Воспроизводится на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\"."</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Произошла ошибка. Повторите попытку."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не найдено."</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Управление недоступно"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index acbc229ed479..91ed10f66e1d 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"මෙහි ක්රීඩා කිරීමට <xliff:g id="DEVICENAME">%1$s</xliff:g> වෙත වඩා සමීප වන්න"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කරමින්"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"අක්රියයි, යෙදුම පරීක්ෂා කරන්න"</string> <string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"පාලනය ලබා ගත නොහැකිය"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• කැමරා යෙදුමක් ස්ථාපන කරන්න"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• යෙදුම සකසා ඇත"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• අවම වශයෙන් එක උපාංගයක් ලැබේ"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ස්පර්ශ කර අල්ලා සිටීමේ කෙටිමඟ"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"අවලංගු කරන්න"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"දැන් පෙරළන්න"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"වඩා හොඳ සෙල්ෆියක් සඳහා දුරකථනය දිගහරින්න"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 3718a20109f7..4c3d8b816347 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa k nemu"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Prehráva sa v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Niečo sa pokazilo. Skúste to znova."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nenájdené"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládač nie je k dispozícii"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Nainštalujte si aplikáciu kamery"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikácia je nastavená"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• K dispozícii je minimálne jedno zariadenie"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržte skratku"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušiť"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Prevráťte"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ak chcete lepšie selfie, rozložte telefón"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 2aee459a43fe..d4996c9f0079 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Približajte napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> za predvajanje v tej napravi"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Prišlo je do napake. Poskusite znova."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolnik ni na voljo"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 06d786fec0d5..ad2e596f849c 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Afrohu te <xliff:g id="DEVICENAME">%1$s</xliff:g> për ta luajtur këtu"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Po luhet në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Ndodhi një gabim. Provo përsëri."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolli është i padisponueshëm"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Të instalosh një aplikacion të kamerës"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Aplikacioni është konfiguruar"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ofrohet të paktën një pajisje"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prek dhe mbaj shtypur shkurtoren"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulo"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"U kthye tani"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Shpalos telefonin për një selfi më të mirë"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index bc660e13ef11..ef6bb4597104 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Приближите се уређају <xliff:g id="DEVICENAME">%1$s</xliff:g> да бисте на њему пуштали"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Пушта се на уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 381f03238d56..c98273926204 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Flytta dig närmare <xliff:g id="DEVICENAME">%1$s</xliff:g> om du vill spela här"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Spelas upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Något gick fel. Försök igen."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Styrning är inte tillgänglig"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• installera en kameraapp"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• appen har konfigurerats"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• minst en enhet är tillgänglig"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tryck länge på genvägen"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vänd nu"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vik upp telefonen för att ta en bättre selfie"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 530bfcc2afa1..5e33bf4d82fc 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sogeza karibu na <xliff:g id="DEVICENAME">%1$s</xliff:g> ili kucheza hapa"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Inacheza kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Hitilafu fulani imetokea. Jaribu tena."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kidhibiti hakipatikani"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Sakinisha programu ya kamera"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Programu hii imewekewa mipangilio"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Angalau kifaa kimoja kinapatikana"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Gusa na ushikilie njia ya mkato"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ghairi"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Geuza kifaa sasa"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Kunjua simu ili upige selfi iliyo bora"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 87d20d6848e4..6e14c2630a03 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"இங்கு பிளே செய்ய உங்கள் சாதனத்தை <xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்திற்கு அருகில் நகர்த்துங்கள்"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் பிளே ஆகிறது"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string> <string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"கட்டுப்பாடு இல்லை"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 2afff20bb7ae..d4e458f78e28 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ఇక్కడ ప్లే చేయడానికి <xliff:g id="DEVICENAME">%1$s</xliff:g>కి దగ్గరగా వెళ్లండి"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g>లో ప్లే అవుతోంది"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"ఏదో తప్పు జరిగింది. మళ్లీ ట్రై చేయండి."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ఇన్యాక్టివ్, యాప్ చెక్ చేయండి"</string> <string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"కంట్రోల్ అందుబాటులో లేదు"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 31a74d13fd72..f8a16bd26483 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"ขยับไปใกล้ <xliff:g id="DEVICENAME">%1$s</xliff:g> มากขึ้นเพื่อเล่นที่นี่"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"กำลังเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"เกิดข้อผิดพลาด โปรดลองอีกครั้ง"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string> <string name="controls_error_removed" msgid="6675638069846014366">"ไม่พบ"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"ใช้การควบคุมไม่ได้"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index cc81e719b2f3..3578aa78c96b 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Lumapit sa <xliff:g id="DEVICENAME">%1$s</xliff:g> para mag-play rito"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Nagpe-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Nagkaproblema. Subukan ulit."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Hindi available ang kontrol"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index a45871d7e488..64431ad25980 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Burada oynatmak için <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaklaşın"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oynatılıyor"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Bir sorun oldu. Tekrar deneyin."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol kullanılamıyor"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Kamera uygulaması yüklenmelidir"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Uygulama kurulmuş olmalıdır"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• En az bir cihaz mevcut olmalıdır"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kısayola dokunup basılı tutun"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"İptal"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Şimdi çevirin"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha iyi selfie çekmek için telefonu açın"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index f00ac9093eac..9eba61007965 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Наблизьтеся до пристрою <xliff:g id="DEVICENAME">%1$s</xliff:g>, щоб відтворити медіафайли на ньому"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Відтворюється на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Сталася помилка. Повторіть спробу."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Елемент керування недоступний"</string> @@ -1004,8 +1006,7 @@ <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Встановлено додаток для камери"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• Додаток налаштовано"</string> <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Принаймні один пристрій доступний"</string> - <!-- no translation found for keyguard_affordance_press_too_short (8145437175134998864) --> - <skip /> + <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Натисніть і утримуйте ярлик"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасувати"</string> <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернути"</string> <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Розгорніть телефон, щоб зробити краще селфі"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index d432ff578ab2..cfcdeca3a2c9 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"یہاں چلانے کے ليے <xliff:g id="DEVICENAME">%1$s</xliff:g> کے قریب جائیں"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چل رہا ہے"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"کچھ غلط ہوگیا۔ پھر کوشش کریں۔"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string> <string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 8c92678c3a4b..83085190c1fa 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Bu yerda ijro qilish uchun <xliff:g id="DEVICENAME">%1$s</xliff:g>qurilmasiga yaqinlashtiring"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"<xliff:g id="DEVICENAME">%1$s</xliff:g> qurilmasida ijro qilinmoqda"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Xatolik yuz berdi. Qayta urining."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Boshqarish imkonsiz"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 4e70744fa149..80aa82293e65 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Di chuyển đến gần <xliff:g id="DEVICENAME">%1$s</xliff:g> hơn để phát tại đây"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Đang phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Đã xảy ra lỗi. Hãy thử lại."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Không có chức năng điều khiển"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index f747730eaaf9..a449e9e332cd 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"若要在此设备上播放,请靠近“<xliff:g id="DEVICENAME">%1$s</xliff:g>”"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"出了点问题,请重试。"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string> <string name="controls_error_removed" msgid="6675638069846014366">"未找到"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"控件不可用"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 01cf0dc557ce..4749e3bc9a97 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在此裝置上播放,請靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string> <string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制功能"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 0c9bf9952c3a..4972aee02a80 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"如要在這部裝置上播放,請移到更靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」的位置"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"正在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string> <string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制項"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 029cbb003eee..d9cf44b3fe3d 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -853,6 +853,8 @@ <string name="media_move_closer_to_end_cast" msgid="6495907340926563656">"Sondela eduze ne-<xliff:g id="DEVICENAME">%1$s</xliff:g> ukuze udlale lapha"</string> <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Idlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string> <string name="media_transfer_failed" msgid="7955354964610603723">"Kukhona okungahambanga kahle. Zama futhi."</string> + <!-- no translation found for media_transfer_loading (5544017127027152422) --> + <skip /> <string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string> <string name="controls_error_removed" msgid="6675638069846014366">"Ayitholakali"</string> <string name="controls_error_removed_title" msgid="1207794911208047818">"Ukulawula akutholakali"</string> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java index 8ee893c14727..359da13a9799 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java @@ -249,7 +249,8 @@ public class RotationButtonController { } public void setRotationLockedAtAngle(int rotationSuggestion) { - RotationPolicy.setRotationLockAtAngle(mContext, true, rotationSuggestion); + RotationPolicy.setRotationLockAtAngle(mContext, /* enabled= */ isRotationLocked(), + /* rotation= */ rotationSuggestion); } public boolean isRotationLocked() { diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index dd6a1bd457b8..1322f16a5a59 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -501,6 +501,17 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } @Override + public void onBiometricsCleared() { + final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric; + mUserUnlockedWithBiometric = + mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( + KeyguardUpdateMonitor.getCurrentUser()); + if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric) { + updateVisibility(); + } + } + + @Override public void onBiometricRunningStateChanged(boolean running, BiometricSourceType biometricSourceType) { final boolean wasRunningFps = mRunningFPS; diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index e40c98892ab5..20ae64cf5985 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -197,6 +197,11 @@ object Flags { @JvmField val UNOCCLUSION_TRANSITION = unreleasedFlag(223, "unocclusion_transition", teamfood = false) + // flag for controlling auto pin confirmation and material u shapes in bouncer + @JvmField + val AUTO_PIN_CONFIRMATION = + unreleasedFlag(224, "auto_pin_confirmation", "auto_pin_confirmation") + // 300 - power menu // TODO(b/254512600): Tracking Bug @JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite") @@ -208,6 +213,10 @@ object Flags { releasedFlag(401, "smartspace_shared_element_transition_enabled") val SMARTSPACE = resourceBooleanFlag(402, R.bool.flag_smartspace, "smartspace") + // TODO(b/258517050): Clean up after the feature is launched. + @JvmField + val SMARTSPACE_DATE_WEATHER_DECOUPLED = unreleasedFlag(403, "smartspace_date_weather_decoupled") + // 500 - quick settings // TODO(b/254512321): Tracking Bug diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 53070a0ab8a7..228320b107cd 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -23,6 +23,7 @@ import android.content.Context import android.graphics.Matrix import android.graphics.Rect import android.os.Handler +import android.os.PowerManager import android.os.RemoteException import android.util.Log import android.view.RemoteAnimationTarget @@ -145,7 +146,8 @@ class KeyguardUnlockAnimationController @Inject constructor( private val featureFlags: FeatureFlags, private val biometricUnlockControllerLazy: Lazy<BiometricUnlockController>, private val statusBarStateController: SysuiStatusBarStateController, - private val notificationShadeWindowController: NotificationShadeWindowController + private val notificationShadeWindowController: NotificationShadeWindowController, + private val powerManager: PowerManager ) : KeyguardStateController.Callback, ISysuiUnlockAnimationController.Stub() { interface KeyguardUnlockAnimationListener { @@ -344,7 +346,7 @@ class KeyguardUnlockAnimationController @Inject constructor( override fun onAnimationEnd(animation: Animator) { Log.d(TAG, "surfaceBehindEntryAnimator#onAnimationEnd") playingCannedUnlockAnimation = false - keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished( + keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */ ) } @@ -579,7 +581,7 @@ class KeyguardUnlockAnimationController @Inject constructor( biometricUnlockControllerLazy.get().isWakeAndUnlock -> { Log.d(TAG, "playCannedUnlockAnimation, isWakeAndUnlock") setSurfaceBehindAppearAmount(1f) - keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished( + keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */) } @@ -627,7 +629,7 @@ class KeyguardUnlockAnimationController @Inject constructor( return@postDelayed } - keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished( + keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */) }, CANNED_UNLOCK_START_DELAY) } @@ -745,7 +747,8 @@ class KeyguardUnlockAnimationController @Inject constructor( !keyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture && dismissAmount >= DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD)) { setSurfaceBehindAppearAmount(1f) - keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(false /* cancelled */) + keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation( + false /* cancelled */) } } @@ -783,10 +786,15 @@ class KeyguardUnlockAnimationController @Inject constructor( surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y ) - // If we're snapping the keyguard back, immediately begin fading it out. - val animationAlpha = - if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount - else surfaceBehindAlpha + + val animationAlpha = when { + // If we're snapping the keyguard back, immediately begin fading it out. + keyguardStateController.isSnappingKeyguardBackAfterSwipe -> amount + // If the screen has turned back off, the unlock animation is going to be cancelled, + // so set the surface alpha to 0f so it's no longer visible. + !powerManager.isInteractive -> 0f + else -> surfaceBehindAlpha + } // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is // unable to draw diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 8aada1f12b0c..bb2141d3fa16 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -144,12 +144,12 @@ import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.DeviceConfigProxy; -import dagger.Lazy; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.concurrent.Executor; +import dagger.Lazy; + /** * Mediates requests related to the keyguard. This includes queries about the * state of the keyguard, power management events that effect whether the keyguard @@ -2725,27 +2725,42 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } /** - * Called if the keyguard exit animation has been cancelled, and we should dismiss to the - * keyguard. + * Called if the keyguard exit animation has been cancelled. * * This can happen due to the system cancelling the RemoteAnimation (due to a timeout, a new - * app transition before finishing the current RemoteAnimation). + * app transition before finishing the current RemoteAnimation, or the keyguard being re-shown). */ private void handleCancelKeyguardExitAnimation() { - showSurfaceBehindKeyguard(); - onKeyguardExitRemoteAnimationFinished(true /* cancelled */); + if (mPendingLock) { + Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. " + + "There's a pending lock, so we were cancelled because the device was locked " + + "again during the unlock sequence. We should end up locked."); + + // A lock is pending, meaning the keyguard exit animation was cancelled because we're + // re-locking. We should just end the surface-behind animation without exiting the + // keyguard. The pending lock will be handled by onFinishedGoingToSleep(). + finishSurfaceBehindRemoteAnimation(true); + } else { + Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. " + + "No pending lock, we should end up unlocked with the app/launcher visible."); + + // No lock is pending, so the animation was cancelled during the unlock sequence, but + // we should end up unlocked. Show the surface and exit the keyguard. + showSurfaceBehindKeyguard(); + exitKeyguardAndFinishSurfaceBehindRemoteAnimation(true /* cancelled */); + } } /** - * Called when we're done running the keyguard exit animation. + * Called when we're done running the keyguard exit animation, we should now end up unlocked. * - * This will call {@link #mSurfaceBehindRemoteAnimationFinishedCallback} to let WM know that - * we're done with the RemoteAnimation, actually hide the keyguard, and clean up state related - * to the keyguard exit animation. + * This will call {@link #handleCancelKeyguardExitAnimation()} to let WM know that we're done + * with the RemoteAnimation, actually hide the keyguard, and clean up state related to the + * keyguard exit animation. * * @param cancelled {@code true} if the animation was cancelled before it finishes. */ - public void onKeyguardExitRemoteAnimationFinished(boolean cancelled) { + public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean cancelled) { Log.d(TAG, "onKeyguardExitRemoteAnimationFinished"); if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) { Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished cancelled=" + cancelled @@ -2774,10 +2789,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, } finishSurfaceBehindRemoteAnimation(cancelled); - mSurfaceBehindRemoteAnimationRequested = false; - - // The remote animation is over, so we're not going away anymore. - mKeyguardStateController.notifyKeyguardGoingAway(false); // Dispatch the callback on animation finishes. mUpdateMonitor.dispatchKeyguardDismissAnimationFinished(); @@ -2836,13 +2847,17 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, return mSurfaceBehindRemoteAnimationRunning; } - /** If it's running, finishes the RemoteAnimation on the surface behind the keyguard. */ + /** + * If it's running, finishes the RemoteAnimation on the surface behind the keyguard and resets + * related state. + * + * This does not set keyguard state to either locked or unlocked, it simply ends the remote + * animation on the surface behind the keyguard. This can be called by + */ void finishSurfaceBehindRemoteAnimation(boolean cancelled) { - if (!mSurfaceBehindRemoteAnimationRunning) { - return; - } - + mSurfaceBehindRemoteAnimationRequested = false; mSurfaceBehindRemoteAnimationRunning = false; + mKeyguardStateController.notifyKeyguardGoingAway(false); if (mSurfaceBehindRemoteAnimationFinishedCallback != null) { try { diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java index db7a145e2ade..15c34430f455 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java @@ -1070,7 +1070,9 @@ public class MediaControlPanel { TurbulenceNoiseAnimationConfig.DEFAULT_OPACITY, /* width= */ mMediaViewHolder.getMultiRippleView().getWidth(), /* height= */ mMediaViewHolder.getMultiRippleView().getHeight(), - TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_DURATION_IN_MILLIS, + TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS, + TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS, + TurbulenceNoiseAnimationConfig.DEFAULT_EASING_DURATION_IN_MILLIS, this.getContext().getResources().getDisplayMetrics().density, BlendMode.PLUS, /* onAnimationEnd= */ null diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt index 154518dceddf..d6ad7d0fb8cf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt @@ -238,6 +238,7 @@ class LockscreenSmartspaceController @Inject constructor( } val ssView = plugin.getView(parent) + ssView.setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD) ssView.registerDataProvider(plugin) ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter { @@ -281,8 +282,10 @@ class LockscreenSmartspaceController @Inject constructor( } val newSession = smartspaceManager.createSmartspaceSession( - SmartspaceConfig.Builder(context, "lockscreen").build()) - Log.d(TAG, "Starting smartspace session for lockscreen") + SmartspaceConfig.Builder( + context, BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD).build()) + Log.d(TAG, "Starting smartspace session for " + + BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD) newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener) this.session = newSession diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java index ae8f419d4e64..e4c41a7ed804 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java @@ -68,6 +68,7 @@ import org.mockito.quality.Strictness; public class LockIconViewControllerBaseTest extends SysuiTestCase { protected static final String UNLOCKED_LABEL = "unlocked"; + protected static final String LOCKED_LABEL = "locked"; protected static final int PADDING = 10; protected MockitoSession mStaticMockSession; @@ -130,6 +131,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase { Rect windowBounds = new Rect(0, 0, 800, 1200); when(mWindowManager.getCurrentWindowMetrics().getBounds()).thenReturn(windowBounds); when(mResources.getString(R.string.accessibility_unlock_button)).thenReturn(UNLOCKED_LABEL); + when(mResources.getString(R.string.accessibility_lock_icon)).thenReturn(LOCKED_LABEL); when(mResources.getDrawable(anyInt(), any())).thenReturn(mIconDrawable); when(mResources.getDimensionPixelSize(R.dimen.lock_icon_padding)).thenReturn(PADDING); when(mAuthController.getScaleFactor()).thenReturn(1f); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java index da40595a4f12..b69491ed1096 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java @@ -262,6 +262,26 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest { // THEN the view is updated to NO translation (no burn-in offsets anymore) verify(mLockIconView).setTranslationY(0); verify(mLockIconView).setTranslationX(0); + } + + @Test + public void lockIconShows_afterBiometricsCleared() { + // GIVEN lock icon controller is initialized and view is attached + init(/* useMigrationFlag= */false); + captureKeyguardUpdateMonitorCallback(); + + // GIVEN user has unlocked with a biometric auth (ie: face auth) + // and biometric running state changes + when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); + mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false, + BiometricSourceType.FACE); + reset(mLockIconView); + + // WHEN biometrics are cleared + when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false); + mKeyguardUpdateMonitorCallback.onBiometricsCleared(); + // THEN the lock icon is shown + verify(mLockIconView).setContentDescription(LOCKED_LABEL); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt index a78c902a1f30..2c81e82f34df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt @@ -4,6 +4,7 @@ import android.app.ActivityManager import android.app.WindowConfiguration import android.graphics.Point import android.graphics.Rect +import android.os.PowerManager import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.RemoteAnimationTarget @@ -19,15 +20,16 @@ import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.phone.BiometricUnlockController import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.util.mockito.whenever import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor.forClass import org.mockito.Mock -import org.mockito.Mockito.`when` import org.mockito.Mockito.mock import org.mockito.Mockito.times import org.mockito.Mockito.verify @@ -56,6 +58,8 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { private lateinit var statusBarStateController: SysuiStatusBarStateController @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController + @Mock + private lateinit var powerManager: PowerManager @Mock private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController.Stub @@ -79,12 +83,13 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { keyguardUnlockAnimationController = KeyguardUnlockAnimationController( context, keyguardStateController, { keyguardViewMediator }, keyguardViewController, featureFlags, { biometricUnlockController }, statusBarStateController, - notificationShadeWindowController + notificationShadeWindowController, powerManager ) keyguardUnlockAnimationController.setLauncherUnlockController( launcherUnlockAnimationController) - `when`(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) + whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java)) + whenever(powerManager.isInteractive).thenReturn(true) // All of these fields are final, so we can't mock them, but are needed so that the surface // appear amount setter doesn't short circuit. @@ -96,6 +101,12 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { keyguardUnlockAnimationController.surfaceTransactionApplier = surfaceTransactionApplier } + @After + fun tearDown() { + keyguardUnlockAnimationController.surfaceBehindEntryAnimator.cancel() + keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.cancel() + } + /** * If we're wake and unlocking, we are animating from the black/AOD screen to the app/launcher * underneath. The LightRevealScrim will animate circularly from the fingerprint reader, @@ -104,7 +115,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun noSurfaceAnimation_ifWakeAndUnlocking() { - `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) + whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, @@ -124,7 +135,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { // Also expect we've immediately asked the keyguard view mediator to finish the remote // animation. - verify(keyguardViewMediator, times(1)).onKeyguardExitRemoteAnimationFinished( + verify(keyguardViewMediator, times(1)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */) verifyNoMoreInteractions(surfaceTransactionApplier) @@ -135,7 +146,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun surfaceAnimation_ifNotWakeAndUnlocking() { - `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(false) + whenever(biometricUnlockController.isWakeAndUnlock).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, @@ -144,7 +155,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { ) // Since the animation is running, we should not have finished the remote animation. - verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished( + verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */) } @@ -159,7 +170,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun fadeInSurfaceBehind_ifRequestedShowSurface_butNotFlinging() { - `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false) + whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(false) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, @@ -181,7 +192,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { */ @Test fun playCannedUnlockAnimation_ifRequestedShowSurface_andFlinging() { - `when`(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true) + whenever(keyguardStateController.isFlingingToDismissKeyguard).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, @@ -215,7 +226,7 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { @Test fun doNotPlayCannedUnlockAnimation_ifLaunchingApp() { - `when`(notificationShadeWindowController.isLaunchingActivity).thenReturn(true) + whenever(notificationShadeWindowController.isLaunchingActivity).thenReturn(true) keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( remoteAnimationTargets, @@ -272,7 +283,53 @@ class KeyguardUnlockAnimationControllerTest : SysuiTestCase() { assertTrue(remainingTargets.isEmpty()) // Since the animation is running, we should not have finished the remote animation. - verify(keyguardViewMediator, times(0)).onKeyguardExitRemoteAnimationFinished( + verify(keyguardViewMediator, times(0)).exitKeyguardAndFinishSurfaceBehindRemoteAnimation( false /* cancelled */) } + + @Test + fun surfaceBehindAlphaOverriddenTo0_ifNotInteractive() { + whenever(powerManager.isInteractive).thenReturn(false) + + keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( + remoteAnimationTargets, + 0 /* startTime */, + false /* requestedShowSurfaceBehindKeyguard */ + ) + + keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f) + + val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java) + verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture()) + + val params = captor.value + + // We expect that we've set the surface behind to alpha = 0f since we're not interactive. + assertEquals(params.alpha, 0f) + assertTrue(params.matrix.isIdentity) + + verifyNoMoreInteractions(surfaceTransactionApplier) + } + + @Test + fun surfaceBehindAlphaNotOverriddenTo0_ifInteractive() { + whenever(powerManager.isInteractive).thenReturn(true) + + keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation( + remoteAnimationTargets, + 0 /* startTime */, + false /* requestedShowSurfaceBehindKeyguard */ + ) + + keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f) + + val captor = forClass(SyncRtSurfaceTransactionApplier.SurfaceParams::class.java) + verify(surfaceTransactionApplier, times(1)).scheduleApply(captor.capture()) + + val params = captor.value + assertEquals(params.alpha, 1f) + assertTrue(params.matrix.isIdentity) + + verifyNoMoreInteractions(surfaceTransactionApplier) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index c38e27aa76bb..5196f4962a6c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -57,6 +57,7 @@ import com.android.keyguard.KeyguardDisplayManager; import com.android.keyguard.KeyguardSecurityView; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.mediator.ScreenOnCoordinator; +import com.android.systemui.DejankUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.biometrics.AuthController; @@ -160,6 +161,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager, mShadeWindowLogger); + DejankUtils.setImmediate(true); + createAndStartViewMediator(); } @@ -357,7 +360,67 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { @Test @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void testCancelKeyguardExitAnimation_noPendingLock_keyguardWillNotBeShowing() { + startMockKeyguardExitAnimation(); + cancelMockKeyguardExitAnimation(); + + // There should not be a pending lock, but try to handle it anyway to ensure one isn't set. + mViewMediator.maybeHandlePendingLock(); + TestableLooper.get(this).processAllMessages(); + + assertFalse(mViewMediator.isShowingAndNotOccluded()); + } + + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void testCancelKeyguardExitAnimationDueToSleep_withPendingLock_keyguardWillBeShowing() { + startMockKeyguardExitAnimation(); + + mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON); + mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false); + + cancelMockKeyguardExitAnimation(); + + mViewMediator.maybeHandlePendingLock(); + TestableLooper.get(this).processAllMessages(); + + assertTrue(mViewMediator.isShowingAndNotOccluded()); + } + + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void testCancelKeyguardExitAnimationThenSleep_withPendingLock_keyguardWillBeShowing() { + startMockKeyguardExitAnimation(); + cancelMockKeyguardExitAnimation(); + + mViewMediator.maybeHandlePendingLock(); + TestableLooper.get(this).processAllMessages(); + + mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON); + mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false); + + mViewMediator.maybeHandlePendingLock(); + TestableLooper.get(this).processAllMessages(); + + assertTrue(mViewMediator.isShowingAndNotOccluded()); + } + + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimation() { + startMockKeyguardExitAnimation(); + assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()); + } + + /** + * Configures mocks appropriately, then starts the keyguard exit animation. + */ + private void startMockKeyguardExitAnimation() { + mViewMediator.onSystemReady(); + TestableLooper.get(this).processAllMessages(); + + mViewMediator.setShowingLocked(true); + RemoteAnimationTarget[] apps = new RemoteAnimationTarget[]{ mock(RemoteAnimationTarget.class) }; @@ -366,10 +429,19 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { }; IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class); + when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true); mViewMediator.startKeyguardExitAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, apps, wallpapers, null, callback); TestableLooper.get(this).processAllMessages(); - assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()); + } + + /** + * Configures mocks appropriately, then cancels the keyguard exit animation. + */ + private void cancelMockKeyguardExitAnimation() { + when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false); + mViewMediator.cancelKeyguardExitAnimation(); + TestableLooper.get(this).processAllMessages(); } private void createAndStartViewMediator() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt index 37f96c8d7023..001e1f4d8086 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt @@ -98,6 +98,8 @@ class DreamSmartspaceControllerTest : SysuiTestCase() { override fun setIsDreaming(isDreaming: Boolean) {} + override fun setUiSurface(uiSurface: String) {} + override fun setDozeAmount(amount: Float) {} override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt index 790865bb496f..ddcf59ec001f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt @@ -55,21 +55,21 @@ import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.time.FakeSystemClock -import java.util.Optional -import java.util.concurrent.Executor import org.junit.Before import org.junit.Test import org.mockito.ArgumentCaptor import org.mockito.Captor import org.mockito.Mock +import org.mockito.Mockito.`when` import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.mock import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations +import java.util.Optional +import java.util.concurrent.Executor @SmallTest class LockscreenSmartspaceControllerTest : SysuiTestCase() { @@ -518,6 +518,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { // THEN the existing session is reused and views are registered verify(smartspaceManager, never()).createSmartspaceSession(any()) + verify(smartspaceView2).setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD) verify(smartspaceView2).registerDataProvider(plugin) } @@ -554,6 +555,7 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { controller.stateChangeListener.onViewAttachedToWindow(view) + verify(smartspaceView).setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD) verify(smartspaceView).registerDataProvider(plugin) verify(smartspaceSession) .addOnTargetsAvailableListener(any(), capture(sessionListenerCaptor)) @@ -642,6 +644,9 @@ class LockscreenSmartspaceControllerTest : SysuiTestCase() { override fun setIsDreaming(isDreaming: Boolean) { } + override fun setUiSurface(uiSurface: String) { + } + override fun setDozeAmount(amount: Float) { } diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt index d25c8c1a5899..614261d476c6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt @@ -17,8 +17,14 @@ package com.android.systemui.surfaceeffects.turbulencenoise import android.graphics.Color import android.testing.AndroidTestingRunner +import android.view.View.INVISIBLE +import android.view.View.VISIBLE import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.EASE_IN +import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.EASE_OUT +import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.MAIN +import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.NOT_PLAYING import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat @@ -33,26 +39,117 @@ class TurbulenceNoiseControllerTest : SysuiTestCase() { private val fakeExecutor = FakeExecutor(fakeSystemClock) @Test - fun play_playsTurbulenceNoise() { - val config = TurbulenceNoiseAnimationConfig(duration = 1000f) + fun play_playsTurbulenceNoiseInOrder() { + val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f) val turbulenceNoiseView = TurbulenceNoiseView(context, null) + val turbulenceNoiseController = TurbulenceNoiseController(turbulenceNoiseView) + + assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING) + + fakeExecutor.execute { + turbulenceNoiseController.play(config) + + assertThat(turbulenceNoiseController.state).isEqualTo(EASE_IN) + + fakeSystemClock.advanceTime(config.easeInDuration.toLong()) + + assertThat(turbulenceNoiseController.state).isEqualTo(MAIN) + + fakeSystemClock.advanceTime(config.maxDuration.toLong()) + + assertThat(turbulenceNoiseController.state).isEqualTo(EASE_OUT) + + fakeSystemClock.advanceTime(config.easeOutDuration.toLong()) + + assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING) + } + } + + @Test + fun play_alreadyPlaying_ignoresNewAnimationRequest() { + val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f) + val turbulenceNoiseView = TurbulenceNoiseView(context, null) + // Currently playing the main animation. + val turbulenceNoiseController = + TurbulenceNoiseController(turbulenceNoiseView).also { it.state = MAIN } + + fakeExecutor.execute { + // Request another animation + turbulenceNoiseController.play(config) + + assertThat(turbulenceNoiseController.state).isEqualTo(MAIN) + } + } + + @Test + fun finish_mainAnimationPlaying_playsEaseOutAnimation() { + val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f) + val turbulenceNoiseView = TurbulenceNoiseView(context, null) + val turbulenceNoiseController = + TurbulenceNoiseController(turbulenceNoiseView).also { it.state = MAIN } + + fakeExecutor.execute { + turbulenceNoiseController.play(config) + + fakeSystemClock.advanceTime(config.maxDuration.toLong() / 2) + + turbulenceNoiseController.finish() + + assertThat(turbulenceNoiseController.state).isEqualTo(EASE_OUT) + } + } + + @Test + fun finish_nonMainAnimationPlaying_doesNotFinishAnimation() { + val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f) + val turbulenceNoiseView = TurbulenceNoiseView(context, null) + val turbulenceNoiseController = + TurbulenceNoiseController(turbulenceNoiseView).also { it.state = EASE_IN } + + fakeExecutor.execute { + turbulenceNoiseController.play(config) + + fakeSystemClock.advanceTime(config.maxDuration.toLong() / 2) + + turbulenceNoiseController.finish() + assertThat(turbulenceNoiseController.state).isEqualTo(EASE_IN) + } + } + + @Test + fun onAnimationFinished_resetsStateCorrectly() { + val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f) + val turbulenceNoiseView = TurbulenceNoiseView(context, null) val turbulenceNoiseController = TurbulenceNoiseController(turbulenceNoiseView) + assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING) + assertThat(turbulenceNoiseView.visibility).isEqualTo(INVISIBLE) + assertThat(turbulenceNoiseView.noiseConfig).isNull() + fakeExecutor.execute { turbulenceNoiseController.play(config) - assertThat(turbulenceNoiseView.isPlaying).isTrue() + assertThat(turbulenceNoiseController.state).isEqualTo(EASE_IN) + assertThat(turbulenceNoiseView.visibility).isEqualTo(VISIBLE) + assertThat(turbulenceNoiseView.noiseConfig).isEqualTo(config) - fakeSystemClock.advanceTime(config.duration.toLong()) + // Play all the animations. + fakeSystemClock.advanceTime( + config.easeInDuration.toLong() + + config.maxDuration.toLong() + + config.easeOutDuration.toLong() + ) - assertThat(turbulenceNoiseView.isPlaying).isFalse() + assertThat(turbulenceNoiseController.state).isEqualTo(NOT_PLAYING) + assertThat(turbulenceNoiseView.visibility).isEqualTo(INVISIBLE) + assertThat(turbulenceNoiseView.noiseConfig).isNull() } } @Test fun updateColor_updatesCorrectColor() { - val config = TurbulenceNoiseAnimationConfig(duration = 1000f, color = Color.WHITE) + val config = TurbulenceNoiseAnimationConfig(maxDuration = 1000f, color = Color.WHITE) val turbulenceNoiseView = TurbulenceNoiseView(context, null) val expectedColor = Color.RED @@ -61,9 +158,9 @@ class TurbulenceNoiseControllerTest : SysuiTestCase() { fakeExecutor.execute { turbulenceNoiseController.play(config) - turbulenceNoiseView.updateColor(expectedColor) + turbulenceNoiseController.updateNoiseColor(expectedColor) - fakeSystemClock.advanceTime(config.duration.toLong()) + fakeSystemClock.advanceTime(config.maxDuration.toLong()) assertThat(config.color).isEqualTo(expectedColor) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt index 633aac076502..ce7f2f4eb6ea 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt @@ -16,7 +16,6 @@ package com.android.systemui.surfaceeffects.turbulencenoise import android.testing.AndroidTestingRunner -import android.view.View import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.util.concurrency.FakeExecutor @@ -34,53 +33,65 @@ class TurbulenceNoiseViewTest : SysuiTestCase() { private val fakeExecutor = FakeExecutor(fakeSystemClock) @Test - fun play_viewHasCorrectVisibility() { - val config = TurbulenceNoiseAnimationConfig(duration = 1000f) - val turbulenceNoiseView = TurbulenceNoiseView(context, null) - - assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE) + fun play_playsAnimation() { + val config = TurbulenceNoiseAnimationConfig() + val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) } + var onAnimationEndCalled = false fakeExecutor.execute { - turbulenceNoiseView.play(config) + turbulenceNoiseView.play(onAnimationEnd = { onAnimationEndCalled = true }) + + fakeSystemClock.advanceTime(config.maxDuration.toLong()) - assertThat(turbulenceNoiseView.visibility).isEqualTo(View.VISIBLE) + assertThat(onAnimationEndCalled).isTrue() + } + } - fakeSystemClock.advanceTime(config.duration.toLong()) + @Test + fun playEaseIn_playsEaseInAnimation() { + val config = TurbulenceNoiseAnimationConfig() + val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) } + var onAnimationEndCalled = false - assertThat(turbulenceNoiseView.visibility).isEqualTo(View.INVISIBLE) + fakeExecutor.execute { + turbulenceNoiseView.playEaseIn(onAnimationEnd = { onAnimationEndCalled = true }) + + fakeSystemClock.advanceTime(config.easeInDuration.toLong()) + + assertThat(onAnimationEndCalled).isTrue() } } @Test - fun play_playsAnimation() { - val config = TurbulenceNoiseAnimationConfig(duration = 1000f) - val turbulenceNoiseView = TurbulenceNoiseView(context, null) + fun playEaseOut_playsEaseOutAnimation() { + val config = TurbulenceNoiseAnimationConfig() + val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) } + var onAnimationEndCalled = false fakeExecutor.execute { - turbulenceNoiseView.play(config) + turbulenceNoiseView.playEaseOut(onAnimationEnd = { onAnimationEndCalled = true }) + + fakeSystemClock.advanceTime(config.easeOutDuration.toLong()) - assertThat(turbulenceNoiseView.isPlaying).isTrue() + assertThat(onAnimationEndCalled).isTrue() } } @Test - fun play_onEnd_triggersOnAnimationEnd() { - var animationEnd = false - val config = - TurbulenceNoiseAnimationConfig( - duration = 1000f, - onAnimationEnd = { animationEnd = true } - ) - val turbulenceNoiseView = TurbulenceNoiseView(context, null) + fun finish_animationPlaying_finishesAnimation() { + val config = TurbulenceNoiseAnimationConfig() + val turbulenceNoiseView = TurbulenceNoiseView(context, null).also { it.applyConfig(config) } + var onAnimationEndCalled = false fakeExecutor.execute { - turbulenceNoiseView.play(config) + turbulenceNoiseView.play(onAnimationEnd = { onAnimationEndCalled = true }) - assertThat(turbulenceNoiseView.isPlaying).isTrue() + assertThat(turbulenceNoiseView.currentAnimator).isNotNull() - fakeSystemClock.advanceTime(config.duration.toLong()) + turbulenceNoiseView.finish() - assertThat(animationEnd).isTrue() + assertThat(onAnimationEndCalled).isTrue() + assertThat(turbulenceNoiseView.currentAnimator).isNull() } } } diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java index babe4eafd8f3..12c16fc43bd3 100644 --- a/services/core/java/com/android/server/notification/SnoozeHelper.java +++ b/services/core/java/com/android/server/notification/SnoozeHelper.java @@ -129,7 +129,7 @@ public final class SnoozeHelper { protected Long getSnoozeTimeForUnpostedNotification(int userId, String pkg, String key) { Long time = null; synchronized (mLock) { - time = mPersistedSnoozedNotifications.get(key); + time = mPersistedSnoozedNotifications.get(getTrimmedString(key)); } if (time == null) { time = 0L; @@ -139,7 +139,7 @@ public final class SnoozeHelper { protected String getSnoozeContextForUnpostedNotification(int userId, String pkg, String key) { synchronized (mLock) { - return mPersistedSnoozedNotificationsWithContext.get(key); + return mPersistedSnoozedNotificationsWithContext.get(getTrimmedString(key)); } } @@ -364,8 +364,9 @@ public final class SnoozeHelper { final NotificationRecord record = mSnoozedNotifications.valueAt(i); if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) { mSnoozedNotifications.removeAt(i); - mPersistedSnoozedNotificationsWithContext.remove(record.getKey()); - mPersistedSnoozedNotifications.remove(record.getKey()); + String trimmedKey = getTrimmedString(record.getKey()); + mPersistedSnoozedNotificationsWithContext.remove(trimmedKey); + mPersistedSnoozedNotifications.remove(trimmedKey); Runnable runnable = () -> { final PendingIntent pi = createPendingIntent(record.getKey()); mAm.cancel(pi); @@ -386,8 +387,9 @@ public final class SnoozeHelper { final NotificationRecord record = mSnoozedNotifications.valueAt(i); if (record.getUserId() == userId) { mSnoozedNotifications.removeAt(i); - mPersistedSnoozedNotificationsWithContext.remove(record.getKey()); - mPersistedSnoozedNotifications.remove(record.getKey()); + String trimmedKey = getTrimmedString(record.getKey()); + mPersistedSnoozedNotificationsWithContext.remove(trimmedKey); + mPersistedSnoozedNotifications.remove(trimmedKey); Runnable runnable = () -> { final PendingIntent pi = createPendingIntent(record.getKey()); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index de0d1f8f76af..5285f63dcc44 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1077,10 +1077,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { // a tendency to hit the power button immediately when they pick up their device, and we // don't want to put the device back to sleep in those cases. final PowerManager.WakeData lastWakeUp = mPowerManagerInternal.getLastWakeup(); - if (lastWakeUp != null && lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE) { - final int gestureDelayMillis = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE, - POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS); + if (lastWakeUp != null && (lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE + || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_LIFT + || lastWakeUp.wakeReason == PowerManager.WAKE_REASON_BIOMETRIC)) { final long now = SystemClock.uptimeMillis(); if (mPowerButtonSuppressionDelayMillis > 0 && (now < lastWakeUp.wakeTime + mPowerButtonSuppressionDelayMillis)) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 9215cabad25a..6b01a7726a43 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -7938,6 +7938,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The smallest screen width is the short side of screen bounds. Because the bounds // and density won't be changed, smallestScreenWidthDp is also fixed. overrideConfig.smallestScreenWidthDp = fullConfig.smallestScreenWidthDp; + // TODO(b/264276741): Check whether the runtime orietnation request is fixed rather than + // the manifest orientation which may be obsolete. if (info.isFixedOrientation()) { // lock rotation too. When in size-compat, onConfigurationChanged will watch for and // apply runtime rotation changes. @@ -8051,8 +8053,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A updateResolvedBoundsPosition(newParentConfiguration); } - if (mVisibleRequested) { - updateCompatDisplayInsets(); + boolean isIgnoreOrientationRequest = mDisplayContent != null + && mDisplayContent.getIgnoreOrientationRequest(); + if (mCompatDisplayInsets == null // for size compat mode set in updateCompatDisplayInsets + // Fixed orientation letterboxing is possible on both large screen devices + // with ignoreOrientationRequest enabled and on phones in split screen even with + // ignoreOrientationRequest disabled. + && (mLetterboxBoundsForFixedOrientationAndAspectRatio != null + // Limiting check for aspect ratio letterboxing to devices with enabled + // ignoreOrientationRequest. This avoids affecting phones where apps may + // not expect the change of smallestScreenWidthDp after rotation which is + // possible with this logic. Not having smallestScreenWidthDp completely + // accurate on phones shouldn't make the big difference and is expected + // to be already well-tested by apps. + || (isIgnoreOrientationRequest && mIsAspectRatioApplied))) { + // TODO(b/264034555): Use mDisplayContent to calculate smallestScreenWidthDp from all + // rotations and only re-calculate if parent bounds have non-orientation size change. + resolvedConfig.smallestScreenWidthDp = + Math.min(resolvedConfig.screenWidthDp, resolvedConfig.screenHeightDp); } // Assign configuration sequence number into hierarchy because there is a different way than @@ -8440,7 +8458,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Calculate app bounds using fixed orientation bounds because they will be needed later // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}. getTaskFragment().computeConfigResourceOverrides(getResolvedOverrideConfiguration(), - newParentConfig); + newParentConfig, mCompatDisplayInsets); mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds); } @@ -9119,6 +9137,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastReportedDisplayId = newDisplayId; } + // Calling from here rather than from onConfigurationChanged because it's possible that + // onConfigurationChanged was called before mVisibleRequested became true and + // mCompatDisplayInsets may not be called again when mVisibleRequested changes. And we + // don't want to save mCompatDisplayInsets in onConfigurationChanged without visibility + // check to avoid remembering obsolete configuration which can lead to unnecessary + // size-compat mode. + if (mVisibleRequested) { + // Calling from here rather than resolveOverrideConfiguration to ensure that this is + // called after full config is updated in ConfigurationContainer#onConfigurationChanged. + updateCompatDisplayInsets(); + } + // Short circuit: if the two full configurations are equal (the common case), then there is // nothing to do. We test the full configuration instead of the global and merged override // configurations because there are cases (like moving a task to the root pinned task) where @@ -9127,12 +9157,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) { ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display " + "unchanged in %s", this); - // It's possible that resolveOverrideConfiguration was called before mVisibleRequested - // became true and mCompatDisplayInsets may not have been created so ensure - // that mCompatDisplayInsets is created here. - if (mVisibleRequested) { - updateCompatDisplayInsets(); - } return true; } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 36f86d10e2c5..75d84eabd146 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5948,6 +5948,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } } + @Nullable ActivityRecord topRunningActivity() { return topRunningActivity(false /* considerKeyguardState */); } diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index cf3a6880e712..e6d8b3db4564 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -100,6 +100,8 @@ public class DisplayRotation { private final DisplayWindowSettings mDisplayWindowSettings; private final Context mContext; private final Object mLock; + @Nullable + private final DisplayRotationImmersiveAppCompatPolicy mCompatPolicyForImmersiveApps; public final boolean isDefaultDisplay; private final boolean mSupportAutoRotation; @@ -205,7 +207,7 @@ public class DisplayRotation { /** * A flag to indicate if the display rotation should be fixed to user specified rotation - * regardless of all other states (including app requrested orientation). {@code true} the + * regardless of all other states (including app requested orientation). {@code true} the * display rotation should be fixed to user specified rotation, {@code false} otherwise. */ private int mFixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT; @@ -232,6 +234,7 @@ public class DisplayRotation { mContext = context; mLock = lock; isDefaultDisplay = displayContent.isDefaultDisplay; + mCompatPolicyForImmersiveApps = initImmersiveAppCompatPolicy(service, displayContent); mSupportAutoRotation = mContext.getResources().getBoolean(R.bool.config_supportAutoRotation); @@ -255,6 +258,14 @@ public class DisplayRotation { } } + @VisibleForTesting + @Nullable + DisplayRotationImmersiveAppCompatPolicy initImmersiveAppCompatPolicy( + WindowManagerService service, DisplayContent displayContent) { + return DisplayRotationImmersiveAppCompatPolicy.createIfNeeded( + service.mLetterboxConfiguration, this, displayContent); + } + // Change the default value to the value specified in the sysprop // ro.bootanim.set_orientation_<display_id>. Four values are supported: ORIENTATION_0, // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270. @@ -1305,11 +1316,11 @@ public class DisplayRotation { return mAllowAllRotations; } - private boolean isLandscapeOrSeascape(int rotation) { + boolean isLandscapeOrSeascape(@Surface.Rotation final int rotation) { return rotation == mLandscapeRotation || rotation == mSeascapeRotation; } - private boolean isAnyPortrait(int rotation) { + boolean isAnyPortrait(@Surface.Rotation final int rotation) { return rotation == mPortraitRotation || rotation == mUpsideDownRotation; } @@ -1348,9 +1359,16 @@ public class DisplayRotation { return mFoldController != null && mFoldController.overrideFrozenRotation(); } - private boolean isRotationChoicePossible(int orientation) { - // Rotation choice is only shown when the user is in locked mode. - if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false; + private boolean isRotationChoiceAllowed(@Surface.Rotation final int proposedRotation) { + final boolean isRotationLockEnforced = mCompatPolicyForImmersiveApps != null + && mCompatPolicyForImmersiveApps.isRotationLockEnforced(proposedRotation); + + // Don't show rotation choice button if + if (!isRotationLockEnforced // not enforcing locked rotation + // and the screen rotation is not locked by the user. + && mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) { + return false; + } // Don't show rotation choice if we are in tabletop or book modes. if (isTabletopAutoRotateOverrideEnabled()) return false; @@ -1402,7 +1420,7 @@ public class DisplayRotation { } // Ensure that some rotation choice is possible for the given orientation. - switch (orientation) { + switch (mCurrentAppOrientation) { case ActivityInfo.SCREEN_ORIENTATION_FULL_USER: case ActivityInfo.SCREEN_ORIENTATION_USER: case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED: @@ -1719,11 +1737,11 @@ public class DisplayRotation { @Override - public void onProposedRotationChanged(int rotation) { + public void onProposedRotationChanged(@Surface.Rotation int rotation) { ProtoLog.v(WM_DEBUG_ORIENTATION, "onProposedRotationChanged, rotation=%d", rotation); // Send interaction power boost to improve redraw performance. mService.mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0); - if (isRotationChoicePossible(mCurrentAppOrientation)) { + if (isRotationChoiceAllowed(rotation)) { final boolean isValid = isValidRotationChoice(rotation); sendProposedRotationChangeToStatusBarInternal(rotation, isValid); } else { diff --git a/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java new file mode 100644 index 000000000000..4dad2b23d3c7 --- /dev/null +++ b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java @@ -0,0 +1,161 @@ +/* + * 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.server.wm; + +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static android.content.res.Configuration.ORIENTATION_UNDEFINED; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; +import static android.view.InsetsState.ITYPE_STATUS_BAR; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.res.Configuration.Orientation; +import android.view.InsetsVisibilities; +import android.view.Surface; + +/** + * Policy to decide whether to enforce screen rotation lock for optimisation of the screen rotation + * user experience for immersive applications for compatibility when ignoring orientation request. + * + * <p>This is needed because immersive apps, such as games, are often not optimized for all + * orientations and can have a poor UX when rotated (e.g., state loss or entering size-compat mode). + * Additionally, some games rely on sensors for the gameplay so users can trigger such rotations + * accidentally when auto rotation is on. + */ +final class DisplayRotationImmersiveAppCompatPolicy { + + @Nullable + static DisplayRotationImmersiveAppCompatPolicy createIfNeeded( + @NonNull final LetterboxConfiguration letterboxConfiguration, + @NonNull final DisplayRotation displayRotation, + @NonNull final DisplayContent displayContent) { + if (!letterboxConfiguration + .isDisplayRotationImmersiveAppCompatPolicyEnabled(/* checkDeviceConfig */ false)) { + return null; + } + + return new DisplayRotationImmersiveAppCompatPolicy( + letterboxConfiguration, displayRotation, displayContent); + } + + private final DisplayRotation mDisplayRotation; + private final LetterboxConfiguration mLetterboxConfiguration; + private final DisplayContent mDisplayContent; + + private DisplayRotationImmersiveAppCompatPolicy( + @NonNull final LetterboxConfiguration letterboxConfiguration, + @NonNull final DisplayRotation displayRotation, + @NonNull final DisplayContent displayContent) { + mDisplayRotation = displayRotation; + mLetterboxConfiguration = letterboxConfiguration; + mDisplayContent = displayContent; + } + + /** + * Decides whether it is necessary to lock screen rotation, preventing auto rotation, based on + * the top activity configuration and proposed screen rotation. + * + * <p>This is needed because immersive apps, such as games, are often not optimized for all + * orientations and can have a poor UX when rotated. Additionally, some games rely on sensors + * for the gameplay so users can trigger such rotations accidentally when auto rotation is on. + * + * <p>Screen rotation is locked when the following conditions are met: + * <ul> + * <li>Top activity requests to hide status and navigation bars + * <li>Top activity is fullscreen and in optimal orientation (without letterboxing) + * <li>Rotation will lead to letterboxing due to fixed orientation. + * <li>{@link DisplayContent#getIgnoreOrientationRequest} is {@code true} + * <li>This policy is enabled on the device, for details see + * {@link LetterboxConfiguration#isDisplayRotationImmersiveAppCompatPolicyEnabled} + * </ul> + * + * @param proposedRotation new proposed {@link Surface.Rotation} for the screen. + * @return {@code true}, if there is a need to lock screen rotation, {@code false} otherwise. + */ + boolean isRotationLockEnforced(@Surface.Rotation final int proposedRotation) { + if (!mLetterboxConfiguration.isDisplayRotationImmersiveAppCompatPolicyEnabled( + /* checkDeviceConfig */ true)) { + return false; + } + synchronized (mDisplayContent.mWmService.mGlobalLock) { + return isRotationLockEnforcedLocked(proposedRotation); + } + } + + private boolean isRotationLockEnforcedLocked(@Surface.Rotation final int proposedRotation) { + if (!mDisplayContent.getIgnoreOrientationRequest()) { + return false; + } + + final ActivityRecord activityRecord = mDisplayContent.topRunningActivity(); + if (activityRecord == null) { + return false; + } + + // Don't lock screen rotation if an activity hasn't requested to hide system bars. + if (!hasRequestedToHideStatusAndNavBars(activityRecord)) { + return false; + } + + // Don't lock screen rotation if activity is not in fullscreen. Checking windowing mode + // for a task rather than an activity to exclude activity embedding scenario. + if (activityRecord.getTask() == null + || activityRecord.getTask().getWindowingMode() != WINDOWING_MODE_FULLSCREEN) { + return false; + } + + // Don't lock screen rotation if activity is letterboxed. + if (activityRecord.areBoundsLetterboxed()) { + return false; + } + + if (activityRecord.getRequestedConfigurationOrientation() == ORIENTATION_UNDEFINED) { + return false; + } + + // Lock screen rotation only if, after rotation the activity's orientation won't match + // the screen orientation, forcing the activity to enter letterbox mode after rotation. + return activityRecord.getRequestedConfigurationOrientation() + != surfaceRotationToConfigurationOrientation(proposedRotation); + } + + /** + * Checks whether activity has requested to hide status and navigation bars. + */ + private boolean hasRequestedToHideStatusAndNavBars(@NonNull ActivityRecord activity) { + WindowState mainWindow = activity.findMainWindow(); + if (mainWindow == null) { + return false; + } + InsetsVisibilities insetsVisibilities = mainWindow.getRequestedVisibilities(); + return !insetsVisibilities.getVisibility(ITYPE_STATUS_BAR) + && !insetsVisibilities.getVisibility(ITYPE_NAVIGATION_BAR); + } + + @Orientation + private int surfaceRotationToConfigurationOrientation(@Surface.Rotation final int rotation) { + if (mDisplayRotation.isAnyPortrait(rotation)) { + return ORIENTATION_PORTRAIT; + } else if (mDisplayRotation.isLandscapeOrSeascape(rotation)) { + return ORIENTATION_LANDSCAPE; + } else { + return ORIENTATION_UNDEFINED; + } + } +} diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index 5e4f2aeb37e4..f916ee40d538 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -18,6 +18,7 @@ package com.android.server.wm; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY; import android.annotation.IntDef; import android.annotation.NonNull; @@ -227,23 +228,35 @@ final class LetterboxConfiguration { // LetterboxUiController#shouldIgnoreRequestedOrientation for details. private final boolean mIsPolicyForIgnoringRequestedOrientationEnabled; - LetterboxConfiguration(Context systemUiContext) { - this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext, - () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext, - /* forBookMode */ false), - () -> readLetterboxVerticalReachabilityPositionFromConfig(systemUiContext, - /* forTabletopMode */ false), - () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext, - /* forBookMode */ true), - () -> readLetterboxVerticalReachabilityPositionFromConfig(systemUiContext, - /* forTabletopMode */ true) - )); + // Whether enabling rotation compat policy for immersive apps that prevents auto rotation + // into non-optimal screen orientation while in fullscreen. This is needed because immersive + // apps, such as games, are often not optimized for all orientations and can have a poor UX + // when rotated. Additionally, some games rely on sensors for the gameplay so users can trigger + // such rotations accidentally when auto rotation is on. + private final boolean mIsDisplayRotationImmersiveAppCompatPolicyEnabled; + + // Flags dynamically updated with {@link android.provider.DeviceConfig}. + @NonNull private final LetterboxConfigurationDeviceConfig mDeviceConfig; + + LetterboxConfiguration(@NonNull final Context systemUiContext) { + this(systemUiContext, + new LetterboxConfigurationPersister(systemUiContext, + () -> readLetterboxHorizontalReachabilityPositionFromConfig( + systemUiContext, /* forBookMode */ false), + () -> readLetterboxVerticalReachabilityPositionFromConfig( + systemUiContext, /* forTabletopMode */ false), + () -> readLetterboxHorizontalReachabilityPositionFromConfig( + systemUiContext, /* forBookMode */ true), + () -> readLetterboxVerticalReachabilityPositionFromConfig( + systemUiContext, /* forTabletopMode */ true))); } @VisibleForTesting - LetterboxConfiguration(Context systemUiContext, - LetterboxConfigurationPersister letterboxConfigurationPersister) { + LetterboxConfiguration(@NonNull final Context systemUiContext, + @NonNull final LetterboxConfigurationPersister letterboxConfigurationPersister) { mContext = systemUiContext; + mDeviceConfig = new LetterboxConfigurationDeviceConfig(systemUiContext.getMainExecutor()); + mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat( R.dimen.config_fixedOrientationLetterboxAspectRatio); mLetterboxActivityCornersRadius = mContext.getResources().getInteger( @@ -284,6 +297,12 @@ final class LetterboxConfiguration { mIsPolicyForIgnoringRequestedOrientationEnabled = mContext.getResources().getBoolean( R.bool.config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled); + mIsDisplayRotationImmersiveAppCompatPolicyEnabled = mContext.getResources().getBoolean( + R.bool.config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled); + mDeviceConfig.updateFlagActiveStatus( + /* isActive */ mIsDisplayRotationImmersiveAppCompatPolicyEnabled, + /* key */ KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY); + mLetterboxConfigurationPersister = letterboxConfigurationPersister; mLetterboxConfigurationPersister.start(); } @@ -1105,4 +1124,20 @@ final class LetterboxConfiguration { mIsCameraCompatRefreshCycleThroughStopEnabled = true; } + /** + * Checks whether rotation compat policy for immersive apps that prevents auto rotation + * into non-optimal screen orientation while in fullscreen is enabled. + * + * <p>This is needed because immersive apps, such as games, are often not optimized for all + * orientations and can have a poor UX when rotated. Additionally, some games rely on sensors + * for the gameplay so users can trigger such rotations accidentally when auto rotation is on. + * + * @param checkDeviceConfig whether should check both static config and a dynamic property + * from {@link DeviceConfig} or only static value. + */ + boolean isDisplayRotationImmersiveAppCompatPolicyEnabled(final boolean checkDeviceConfig) { + return mIsDisplayRotationImmersiveAppCompatPolicyEnabled && (!checkDeviceConfig + || mDeviceConfig.getFlag(KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY)); + } + } diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java new file mode 100644 index 000000000000..cf123a1f9ace --- /dev/null +++ b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java @@ -0,0 +1,120 @@ +/* + * 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.server.wm; + +import android.annotation.NonNull; +import android.provider.DeviceConfig; +import android.util.ArraySet; + + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.Map; +import java.util.concurrent.Executor; + +/** + * Utility class that caches {@link DeviceConfig} flags for app compat features and listens + * to updates by implementing {@link DeviceConfig.OnPropertiesChangedListener}. + */ +final class LetterboxConfigurationDeviceConfig + implements DeviceConfig.OnPropertiesChangedListener { + + static final String KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY = + "enable_display_rotation_immersive_app_compat_policy"; + private static final boolean DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY = + true; + + @VisibleForTesting + static final Map<String, Boolean> sKeyToDefaultValueMap = Map.of( + KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY, + DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY + ); + + // Whether enabling rotation compat policy for immersive apps that prevents auto rotation + // into non-optimal screen orientation while in fullscreen. This is needed because immersive + // apps, such as games, are often not optimized for all orientations and can have a poor UX + // when rotated. Additionally, some games rely on sensors for the gameplay so users can trigger + // such rotations accidentally when auto rotation is on. + private boolean mIsDisplayRotationImmersiveAppCompatPolicyEnabled = + DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY; + + // Set of active device configs that need to be updated in + // DeviceConfig.OnPropertiesChangedListener#onPropertiesChanged. + private final ArraySet<String> mActiveDeviceConfigsSet = new ArraySet<>(); + + LetterboxConfigurationDeviceConfig(@NonNull final Executor executor) { + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER, + executor, /* onPropertiesChangedListener */ this); + } + + @Override + public void onPropertiesChanged(@NonNull final DeviceConfig.Properties properties) { + for (int i = mActiveDeviceConfigsSet.size() - 1; i >= 0; i--) { + String key = mActiveDeviceConfigsSet.valueAt(i); + // Reads the new configuration, if the device config properties contain the key. + if (properties.getKeyset().contains(key)) { + readAndSaveValueFromDeviceConfig(key); + } + } + } + + /** + * Adds {@code key} to a set of flags that can be updated from the server if + * {@code isActive} is {@code true} and read it's current value from {@link DeviceConfig}. + */ + void updateFlagActiveStatus(boolean isActive, String key) { + if (!isActive) { + return; + } + mActiveDeviceConfigsSet.add(key); + readAndSaveValueFromDeviceConfig(key); + } + + /** + * Returns values of the {@code key} flag. + * + * @throws AssertionError {@code key} isn't recognised. + */ + boolean getFlag(String key) { + switch (key) { + case KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY: + return mIsDisplayRotationImmersiveAppCompatPolicyEnabled; + default: + throw new AssertionError("Unexpected flag name: " + key); + } + } + + private void readAndSaveValueFromDeviceConfig(String key) { + Boolean defaultValue = sKeyToDefaultValueMap.get(key); + if (defaultValue == null) { + throw new AssertionError("Haven't found default value for flag: " + key); + } + switch (key) { + case KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY: + mIsDisplayRotationImmersiveAppCompatPolicyEnabled = + getDeviceConfig(key, defaultValue); + break; + default: + throw new AssertionError("Unexpected flag name: " + key); + } + } + + private boolean getDeviceConfig(String key, boolean defaultValue) { + return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER, + key, defaultValue); + } +} diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 689cae5777cd..22da56ad4d3b 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -2138,7 +2138,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { final Rect parentBounds = parentConfig.windowConfiguration.getBounds(); final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds(); - if (resolvedBounds == null || resolvedBounds.isEmpty()) { + if (resolvedBounds.isEmpty()) { mTmpFullBounds.set(parentBounds); insideParentBounds = true; } else { @@ -2227,6 +2227,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { : overrideScreenHeightDp; } + // TODO(b/238331848): Consider simplifying logic that computes smallestScreenWidthDp. if (inOutConfig.smallestScreenWidthDp == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { // When entering to or exiting from Pip, the PipTaskOrganizer will set the diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 700016be62f8..fb584feeaf04 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -3759,7 +3759,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (mSyncState == SYNC_STATE_NONE) return false; mSyncState = SYNC_STATE_READY; mSyncMethodOverride = BLASTSyncEngine.METHOD_UNDEFINED; - mWmService.mWindowPlacerLocked.requestTraversal(); ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "onSyncFinishedDrawing %s", this); return true; } @@ -3829,8 +3828,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< /** * Checks if the subtree rooted at this container is finished syncing (everything is ready or - * not visible). NOTE, this is not const: it will cancel/prepare itself depending on its state - * in the hierarchy. + * not visible). NOTE, this is not const: it may cancel/prepare/complete itself depending on + * its state in the hierarchy. * * @return {@code true} if this subtree is finished waiting for sync participants. */ diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b3a7754bc2d5..4e32a7ca3bf4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2587,12 +2587,6 @@ public class WindowManagerService extends IWindowManager.Stub && win.mSyncSeqId > lastSyncSeqId) { maybeSyncSeqId = win.shouldSyncWithBuffers() ? win.mSyncSeqId : -1; win.markRedrawForSyncReported(); - if (win.mSyncState == WindowContainer.SYNC_STATE_WAITING_FOR_DRAW - && winAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN - && maybeSyncSeqId < 0) { - // Do not wait for a drawn window which won't report draw. - win.onSyncFinishedDrawing(); - } } else { maybeSyncSeqId = -1; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 2f55d1824c07..04699619bfc8 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -6004,12 +6004,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override boolean isSyncFinished() { - if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW && mViewVisibility != View.VISIBLE - && !isVisibleRequested()) { + if (!isVisibleRequested()) { // Don't wait for invisible windows. However, we don't alter the state in case the // window becomes visible while the sync group is still active. return true; } + if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW && mWinAnimator.mDrawState == HAS_DRAWN + && !mRedrawForSyncReported && !mWmService.mResizingWindows.contains(this)) { + // Complete the sync state immediately for a drawn window that doesn't need to redraw. + onSyncFinishedDrawing(); + } return super.isSyncFinished(); } @@ -6060,6 +6064,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final boolean hasSyncHandlers = executeDrawHandlers(postDrawTransaction, syncSeqId); boolean skipLayout = false; + boolean layoutNeeded = false; // Control the timing to switch the appearance of window with different rotations. final AsyncRotationController asyncRotationController = mDisplayContent.getAsyncRotationController(); @@ -6072,7 +6077,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } else if (syncActive) { // Currently in a Sync that is using BLAST. if (!syncStillPending) { - onSyncFinishedDrawing(); + layoutNeeded = onSyncFinishedDrawing(); } if (postDrawTransaction != null) { mSyncTransaction.merge(postDrawTransaction); @@ -6081,10 +6086,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } else if (useBLASTSync()) { // Sync that is not using BLAST - onSyncFinishedDrawing(); + layoutNeeded = onSyncFinishedDrawing(); } - final boolean layoutNeeded = + layoutNeeded |= mWinAnimator.finishDrawingLocked(postDrawTransaction, mClientWasDrawingForSync); mClientWasDrawingForSync = false; // We always want to force a traversal after a finish draw for blast sync. diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java index 1f117b3697c9..9c3d5a7fb6d9 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java @@ -234,7 +234,7 @@ public class SnoozeHelperTest extends UiServiceTestCase { } @Test - public void testScheduleRepostsForLongTagPersistedNotification() throws Exception { + public void testLongTagPersistedNotification() throws Exception { String longTag = "A".repeat(66000); NotificationRecord r = getNotificationRecord("pkg", 1, longTag, UserHandle.SYSTEM); mSnoozeHelper.snooze(r, 0); @@ -612,7 +612,8 @@ public class SnoozeHelperTest extends UiServiceTestCase { public void testClearData_userPackage() { // snooze 2 from same package NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); - NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM); + NotificationRecord r2 = getNotificationRecord("pkg", 2, "two" + "2".repeat(66000), + UserHandle.SYSTEM); // include notif with very long tag mSnoozeHelper.snooze(r, 1000); mSnoozeHelper.snooze(r2, 1000); assertTrue(mSnoozeHelper.isSnoozed( @@ -634,11 +635,14 @@ public class SnoozeHelperTest extends UiServiceTestCase { @Test public void testClearData_user() { - // snooze 2 from same package + // snooze 2 from same package, including notifs with long tag NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); - NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two", UserHandle.SYSTEM); - NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", UserHandle.SYSTEM); - NotificationRecord r4 = getNotificationRecord("pkg", 2, "two", UserHandle.ALL); + NotificationRecord r2 = getNotificationRecord("pkg2", 2, "two" + "2".repeat(66000), + UserHandle.SYSTEM); + NotificationRecord r3 = getNotificationRecord("pkg2", 3, "three", + UserHandle.SYSTEM); + NotificationRecord r4 = getNotificationRecord("pkg", 2, "two" + "2".repeat(66000), + UserHandle.ALL); mSnoozeHelper.snooze(r, 1000); mSnoozeHelper.snooze(r2, 1000); mSnoozeHelper.snooze(r3, "until"); @@ -653,6 +657,19 @@ public class SnoozeHelperTest extends UiServiceTestCase { assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_ALL, r4.getSbn().getPackageName(), r4.getKey())); + assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification( + r.getUser().getIdentifier(), r.getSbn().getPackageName(), + r.getSbn().getKey())); + assertFalse(0L == mSnoozeHelper.getSnoozeTimeForUnpostedNotification( + r2.getUser().getIdentifier(), r2.getSbn().getPackageName(), + r2.getSbn().getKey())); + assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( + r3.getUser().getIdentifier(), r3.getSbn().getPackageName(), + r3.getSbn().getKey())); + assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( + r4.getUser().getIdentifier(), r4.getSbn().getPackageName(), + r4.getSbn().getKey())); + // clear data mSnoozeHelper.clearData(UserHandle.USER_SYSTEM); @@ -666,18 +683,18 @@ public class SnoozeHelperTest extends UiServiceTestCase { assertTrue(mSnoozeHelper.isSnoozed( UserHandle.USER_SYSTEM, r4.getSbn().getPackageName(), r4.getKey())); - assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( - r3.getUser().getIdentifier(), r3.getSbn().getPackageName(), - r3.getSbn().getKey())); - assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( - r4.getUser().getIdentifier(), r4.getSbn().getPackageName(), - r4.getSbn().getKey())); assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification( r.getUser().getIdentifier(), r.getSbn().getPackageName(), r.getSbn().getKey()).longValue()); assertEquals(0L, mSnoozeHelper.getSnoozeTimeForUnpostedNotification( r2.getUser().getIdentifier(), r2.getSbn().getPackageName(), r2.getSbn().getKey()).longValue()); + assertNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( + r3.getUser().getIdentifier(), r3.getSbn().getPackageName(), + r3.getSbn().getKey())); + assertNotNull(mSnoozeHelper.getSnoozeContextForUnpostedNotification( + r4.getUser().getIdentifier(), r4.getSbn().getPackageName(), + r4.getSbn().getKey())); // 2 for initial timed-snoozes, once each for canceling the USER_SYSTEM snoozes verify(mAm, times(5)).cancel(any(PendingIntent.class)); diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp index 079d765868fd..2ce7cea08a3d 100644 --- a/services/tests/wmtests/Android.bp +++ b/services/tests/wmtests/Android.bp @@ -68,6 +68,10 @@ android_test { "android.test.runner", ], + defaults: [ + "modules-utils-testable-device-config-defaults", + ], + // These are not normally accessible from apps so they must be explicitly included. jni_libs: [ "libdexmakerjvmtiagent", diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java new file mode 100644 index 000000000000..def4b88701af --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java @@ -0,0 +1,225 @@ +/* + * 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.server.wm; + +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; +import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; +import static android.content.res.Configuration.ORIENTATION_UNDEFINED; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; +import static android.view.InsetsState.ITYPE_STATUS_BAR; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyBoolean; + +import android.platform.test.annotations.Presubmit; +import android.view.InsetsVisibilities; +import android.view.Surface; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test class for {@link DisplayRotationImmersiveAppCompatPolicy}. + * + * Build/Install/Run: + * atest WmTests:DisplayRotationImmersiveAppCompatPolicyTests + */ +@SmallTest +@Presubmit +@RunWith(WindowTestRunner.class) +public class DisplayRotationImmersiveAppCompatPolicyTests extends WindowTestsBase { + + private DisplayRotationImmersiveAppCompatPolicy mPolicy; + + private LetterboxConfiguration mMockLetterboxConfiguration; + private ActivityRecord mMockActivityRecord; + private Task mMockTask; + private InsetsVisibilities mMockInsetsVisibilities; + + @Before + public void setUp() throws Exception { + mMockActivityRecord = mock(ActivityRecord.class); + mMockTask = mock(Task.class); + when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_FULLSCREEN); + when(mMockActivityRecord.getTask()).thenReturn(mMockTask); + when(mMockActivityRecord.areBoundsLetterboxed()).thenReturn(false); + when(mMockActivityRecord.getRequestedConfigurationOrientation()).thenReturn( + ORIENTATION_LANDSCAPE); + WindowState mockWindowState = mock(WindowState.class); + mMockInsetsVisibilities = mock(InsetsVisibilities.class); + when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_STATUS_BAR))).thenReturn(false); + when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_NAVIGATION_BAR))).thenReturn(false); + when(mockWindowState.getRequestedVisibilities()).thenReturn(mMockInsetsVisibilities); + when(mMockActivityRecord.findMainWindow()).thenReturn(mockWindowState); + + spy(mDisplayContent); + doReturn(mMockActivityRecord).when(mDisplayContent).topRunningActivity(); + when(mDisplayContent.getIgnoreOrientationRequest()).thenReturn(true); + + mMockLetterboxConfiguration = mock(LetterboxConfiguration.class); + when(mMockLetterboxConfiguration.isDisplayRotationImmersiveAppCompatPolicyEnabled( + /* checkDeviceConfig */ anyBoolean())).thenReturn(true); + + mPolicy = DisplayRotationImmersiveAppCompatPolicy.createIfNeeded( + mMockLetterboxConfiguration, createDisplayRotationMock(), + mDisplayContent); + } + + private DisplayRotation createDisplayRotationMock() { + DisplayRotation mockDisplayRotation = mock(DisplayRotation.class); + + when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_0)).thenReturn(true); + when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_90)).thenReturn(false); + when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_180)).thenReturn(true); + when(mockDisplayRotation.isAnyPortrait(Surface.ROTATION_270)).thenReturn(false); + when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_0)).thenReturn(false); + when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_90)).thenReturn(true); + when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_180)).thenReturn(false); + when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_270)).thenReturn(true); + + return mockDisplayRotation; + } + + @Test + public void testIsRotationLockEnforced_landscapeActivity_lockedWhenRotatingToPortrait() { + // Base case: App is optimal in Landscape. + + // ROTATION_* is the target display orientation counted from the natural display + // orientation. Outside of test environment, ROTATION_0 means that proposed display + // rotation is the natural device orientation. + // DisplayRotationImmersiveAppCompatPolicy assesses whether the proposed target + // orientation ROTATION_* is optimal for the top fullscreen activity or not. + // For instance, ROTATION_0 means portrait screen orientation (see + // createDisplayRotationMock) which isn't optimal for a landscape-only activity so + // we should show a rotation suggestion button instead of rotating directly. + + // Rotation to portrait + assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_0)); + // Rotation to landscape + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_90)); + // Rotation to portrait + assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_180)); + // Rotation to landscape + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_270)); + } + + @Test + public void testIsRotationLockEnforced_portraitActivity_lockedWhenRotatingToLandscape() { + when(mMockActivityRecord.getRequestedConfigurationOrientation()).thenReturn( + ORIENTATION_PORTRAIT); + + // Rotation to portrait + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_0)); + // Rotation to landscape + assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_90)); + // Rotation to portrait + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_180)); + // Rotation to landscape + assertTrue(mPolicy.isRotationLockEnforced(Surface.ROTATION_270)); + } + + @Test + public void testIsRotationLockEnforced_responsiveActivity_lockNotEnforced() { + // Do not fix screen orientation + when(mMockActivityRecord.getRequestedConfigurationOrientation()).thenReturn( + ORIENTATION_UNDEFINED); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + @Test + public void testIsRotationLockEnforced_statusBarVisible_lockNotEnforced() { + // Some system bars are visible + when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_STATUS_BAR))).thenReturn(true); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + @Test + public void testIsRotationLockEnforced_navBarVisible_lockNotEnforced() { + // Some system bars are visible + when(mMockInsetsVisibilities.getVisibility(eq(ITYPE_NAVIGATION_BAR))).thenReturn(true); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + @Test + public void testIsRotationLockEnforced_activityIsLetterboxed_lockNotEnforced() { + // Activity is letterboxed + when(mMockActivityRecord.areBoundsLetterboxed()).thenReturn(true); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + @Test + public void testIsRotationLockEnforced_notFullscreen_lockNotEnforced() { + when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_MULTI_WINDOW); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + + when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_PINNED); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + + when(mMockTask.getWindowingMode()).thenReturn(WINDOWING_MODE_FREEFORM); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + @Test + public void testIsRotationLockEnforced_ignoreOrientationRequestDisabled_lockNotEnforced() { + when(mDisplayContent.getIgnoreOrientationRequest()).thenReturn(false); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + @Test + public void testRotationChoiceEnforcedOnly_nullTopRunningActivity_lockNotEnforced() { + when(mDisplayContent.topRunningActivity()).thenReturn(null); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + @Test + public void testRotationChoiceEnforcedOnly_featureFlagDisabled_lockNotEnforced() { + when(mMockLetterboxConfiguration.isDisplayRotationImmersiveAppCompatPolicyEnabled( + /* checkDeviceConfig */ true)).thenReturn(false); + + assertIsRotationLockEnforcedReturnsFalseForAllRotations(); + } + + private void assertIsRotationLockEnforcedReturnsFalseForAllRotations() { + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_0)); + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_90)); + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_180)); + assertFalse(mPolicy.isRotationLockEnforced(Surface.ROTATION_270)); + } +} diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index 491f876dceed..4ce43e1fc469 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -1096,8 +1096,16 @@ public class DisplayRotationTests { mMockDisplayAddress = mock(DisplayAddress.class); mMockDisplayWindowSettings = mock(DisplayWindowSettings.class); + mTarget = new DisplayRotation(sMockWm, mMockDisplayContent, mMockDisplayAddress, - mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext, new Object()); + mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext, new Object()) { + @Override + DisplayRotationImmersiveAppCompatPolicy initImmersiveAppCompatPolicy( + WindowManagerService service, DisplayContent displayContent) { + return null; + } + }; + reset(sMockWm); captureObservers(); diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationDeviceConfigTests.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationDeviceConfigTests.java new file mode 100644 index 000000000000..2b7a06bd35f3 --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationDeviceConfigTests.java @@ -0,0 +1,109 @@ +/* + * 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.server.wm; + +import static com.android.server.wm.LetterboxConfigurationDeviceConfig.sKeyToDefaultValueMap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.platform.test.annotations.Presubmit; +import android.provider.DeviceConfig; + +import androidx.test.filters.SmallTest; + +import com.android.modules.utils.testing.TestableDeviceConfig; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import java.util.Map; + +/** + * Test class for {@link LetterboxConfigurationDeviceConfig}. + * + * atest WmTests:LetterboxConfigurationDeviceConfigTests + */ +@SmallTest +@Presubmit +public class LetterboxConfigurationDeviceConfigTests { + + private LetterboxConfigurationDeviceConfig mDeviceConfig; + + @Rule + public final TestableDeviceConfig.TestableDeviceConfigRule + mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule(); + + @Before + public void setUp() { + mDeviceConfig = new LetterboxConfigurationDeviceConfig(/* executor */ Runnable::run); + } + + @Test + public void testGetFlag_flagIsActive_flagChanges() throws Throwable { + for (Map.Entry<String, Boolean> entry : sKeyToDefaultValueMap.entrySet()) { + testGetFlagForKey_flagIsActive_flagChanges(entry.getKey(), entry.getValue()); + } + } + + private void testGetFlagForKey_flagIsActive_flagChanges(final String key, boolean defaultValue) + throws InterruptedException { + mDeviceConfig.updateFlagActiveStatus(/* isActive */ true, key); + + assertEquals("Unexpected default value for " + key, + mDeviceConfig.getFlag(key), defaultValue); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key, + /* value */ Boolean.TRUE.toString(), /* makeDefault */ false); + + assertTrue("Flag " + key + "is not true after change", mDeviceConfig.getFlag(key)); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key, + /* value */ Boolean.FALSE.toString(), /* makeDefault */ false); + + assertFalse("Flag " + key + "is not false after change", mDeviceConfig.getFlag(key)); + } + + @Test + public void testGetFlag_flagIsNotActive_alwaysReturnDefaultValue() throws Throwable { + for (Map.Entry<String, Boolean> entry : sKeyToDefaultValueMap.entrySet()) { + testGetFlagForKey_flagIsNotActive_alwaysReturnDefaultValue( + entry.getKey(), entry.getValue()); + } + } + + private void testGetFlagForKey_flagIsNotActive_alwaysReturnDefaultValue(final String key, + boolean defaultValue) throws InterruptedException { + assertEquals("Unexpected default value for " + key, + mDeviceConfig.getFlag(key), defaultValue); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key, + /* value */ Boolean.TRUE.toString(), /* makeDefault */ false); + + assertEquals("Flag " + key + "is not set to default after change", + mDeviceConfig.getFlag(key), defaultValue); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, key, + /* value */ Boolean.FALSE.toString(), /* makeDefault */ false); + + assertEquals("Flag " + key + "is not set to default after change", + mDeviceConfig.getFlag(key), defaultValue); + } + +} diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index e9080ab78fbc..a8e91980014e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -1617,6 +1617,79 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testComputeConfigResourceOverrides_unresizableApp() { + // Set up a display in landscape and ignoring orientation request. + setUpDisplaySizeWithApp(2800, 1400); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + + final Rect activityBounds = new Rect(mActivity.getBounds()); + + int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp; + int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp; + + // App should launch in fixed orientation letterbox. + // Activity bounds should be 700x1400 with the ratio as the display. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + assertFitted(); + assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp); + assertTrue(originalScreenWidthDp < originalScreenHeighthDp); + + // Rotate display to portrait. + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + // After we rotate, the activity should go in the size-compat mode and report the same + // configuration values. + assertScaled(); + assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp); + assertEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp); + assertEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp); + + // Restart activity + mActivity.restartProcessIfVisible(); + + // Now configuration should be updated + assertFitted(); + assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp); + assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp); + assertEquals(mActivity.getConfiguration().screenWidthDp, + mActivity.getConfiguration().smallestScreenWidthDp); + } + + @Test + public void testComputeConfigResourceOverrides_resizableFixedOrientationActivity() { + // Set up a display in landscape and ignoring orientation request. + setUpDisplaySizeWithApp(2800, 1400); + mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + // Portrait fixed app without max aspect. + prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, false /* isUnresizable */); + + final Rect activityBounds = new Rect(mActivity.getBounds()); + + int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp; + int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp; + + // App should launch in fixed orientation letterbox. + // Activity bounds should be 700x1400 with the ratio as the display. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + assertFitted(); + assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp); + assertTrue(originalScreenWidthDp < originalScreenHeighthDp); + + // Rotate display to portrait. + rotateDisplay(mActivity.mDisplayContent, ROTATION_90); + + // Now configuration should be updated + assertFitted(); + assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp); + assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp); + assertEquals(mActivity.getConfiguration().screenWidthDp, + mActivity.getConfiguration().smallestScreenWidthDp); + } + + @Test public void testSplitAspectRatioForUnresizablePortraitApps() { // Set up a display in landscape and ignoring orientation request. int screenWidth = 1600; diff --git a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java index df7b3cdebe28..aff9c1a9372a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java @@ -31,6 +31,7 @@ import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -108,9 +109,7 @@ public class SyncEngineTests extends WindowTestsBase { bse.onSurfacePlacement(); verify(listener, times(0)).onTransactionReady(anyInt(), any()); - mockWC.onSyncFinishedDrawing(); - // Make sure the second traversal is requested. - verify(mWm.mWindowPlacerLocked, times(2)).requestTraversal(); + assertTrue(mockWC.onSyncFinishedDrawing()); bse.onSurfacePlacement(); verify(listener, times(1)).onTransactionReady(eq(id), notNull()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index df3b306d6739..fa98537f8909 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -1240,7 +1240,8 @@ public class WindowOrganizerTests extends WindowTestsBase { assertTrue(w1.useBLASTSync()); assertTrue(w2.useBLASTSync()); - w1.immediatelyNotifyBlastSync(); + // A drawn window can complete the sync state automatically. + w1.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN; mWm.mSyncEngine.onSurfacePlacement(); verify(mockCallback).onTransactionReady(anyInt(), any()); assertFalse(w1.useBLASTSync()); |